home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tex / macros / source / contrib / supported / xypic / src / xy.doc < prev    next >
Text File  |  1995-03-15  |  223KB  |  6,531 lines

  1. %% $Id: xy.doc,v 2.12 1994/10/25 11:55:12 kris Exp $
  2. %%
  3. %% Basic XY-pictures: XY-pic bootstrap and kernel macros.
  4. %% Copyright (c) 1991-1994     Kristoffer H. Rose  <kris@diku.dk>
  5. %%
  6. %% This file is part of the XY-pic package for graphs and diagrams in TeX.
  7. %% Copyright (c) 1991-1994     Kristoffer H. Rose  <kris@diku.dk>
  8. %%
  9. %% The XY-pic package is free software; you can redistribute it and/or modify
  10. %% it under the terms of the GNU General Public License as published by the
  11. %% Free Software Foundation; either version 2 of the License, or (at your
  12. %% option) any later version.
  13. %%
  14. %% The XY-pic package is distributed in the hope that it will be useful, but
  15. %% WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. %% or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17. %% for more details.
  18. %%
  19. %% You should have received a copy of the GNU General Public License along
  20. %% with this package; if not, write to the Free Software Foundation, Inc.,
  21. %% 675 Mass Ave, Cambridge, MA 02139, USA.
  22. %%
  23. \ifx\xyloaded\undefined\else \message{not reloaded}\endinput \fi
  24. \let\xyloaded=\relax
  25.  
  26. % NOTE: Apart from the actual macros (as also found in xy.tex), this file
  27. % contains both the XY-pic kernel reference manual and TeXnical documentation.
  28. % See xyrefer.man and xysource.man for how to typeset this information.
  29.  
  30. \message{Bootstrap\string'ing\string:}
  31.  
  32. {\catcode96 12\catcode`\#6\catcode`\.12\catcode`\:12\catcode`\'12\catcode`\@11
  33. \ifx\xywarnifdefined\undefined\else \immediate\write16{}%
  34.  \immediate\write16{%
  35.   XY-pic Warning: \string\xywarnifdefined\space redefined.}%
  36.  \immediate\write16{}\fi
  37. \gdef\xywarnifdefined#1{\ifx#1\undefined\else \immediate\write16{}%
  38.  \immediate\write16{%
  39.   XY-pic Warning: `\string#1' redefined.}\immediate\write16{}\fi}
  40. \xywarnifdefined\xydef@ \gdef\xydef@#1{\xywarnifdefined#1\def#1}
  41. \xywarnifdefined\xylet@ \gdef\xylet@#1{\xywarnifdefined#1\let#1}
  42. \xywarnifdefined\xynew@
  43.  \gdef\xynew@#1#2{\xywarnifdefined#2\csname new#1\endcsname#2}}
  44.  
  45. \message{catcodes\string,}
  46.  
  47. \xywarnifdefined\xyuncatcodes \edef\xyuncatcodes{%
  48.  \catcode92 0 \catcode123 1 \catcode125 2 \catcode37 14
  49.  \catcode 9 \the\catcode 9 \catcode10 \the\catcode10 \catcode12 \the\catcode12
  50.  \catcode35 \the\catcode35 \catcode36 \the\catcode36 \catcode38 \the\catcode38 
  51.  \catcode43 \the\catcode43 \catcode45 \the\catcode45 \catcode46 \the\catcode46 
  52.  \catcode47 \the\catcode47 
  53.  \catcode60 \the\catcode60 \catcode61 \the\catcode61 \catcode62 \the\catcode62 
  54.  \catcode64 \the\catcode64 \catcode96 \the\catcode96
  55.  \newlinechar \the\newlinechar \endlinechar \the\endlinechar }
  56.  
  57. \xywarnifdefined\xycatcodes \def\xycatcodes{%
  58.  \catcode 9 10
  59.  \catcode35  6 \catcode 36 3 \catcode 38 4
  60.  \catcode43 12 \catcode 45 12 \catcode 46 12 \catcode 47 12
  61.  \catcode60 12 \catcode 61 12 \catcode 62 12
  62.  \catcode64 11 \catcode 96 12 }
  63.  
  64. \xycatcodes
  65.  
  66. \message{docmode,}
  67.  
  68. {\catcode`\|0 \xywarnifdefined|DOCMODE
  69. \gdef|DOCMODE#1{\ifx(#1\relax \xycatcodes \expandafter\ignorespaces
  70.  \else \skipspecials@ \expandafter\docm@\fi}%
  71.  
  72. \xywarnifdefined\skipspecials@
  73. \gdef\skipspecials@{%
  74.  \catcode`\\12 \catcode`\{12 \catcode`\}12 \catcode`\#12 \catcode`\%12
  75.  \catcode`\^^L12 \endlinechar`\^^J }%
  76.  
  77. \catcode`\/=12 \lccode`\/`\\%
  78. \lccode`\D`\D \lccode`\O`\O \lccode`\C`\C \lccode`\M`\M \lccode`\E`\E
  79. \lowercase{%
  80. \xywarnifdefined\docm@ \gdef\docm@{\docm@i}%
  81. \xywarnifdefined\docm@i \gdef\docm@i#1^^J{\docm@ii#1/DOCMODE\docm@iii}%
  82. \xywarnifdefined\docm@ii
  83.  \gdef\docm@ii#1/DOCMODE{\def\next@{#1}\futurelet\next\docm@iii}%
  84. \xywarnifdefined\docm@iii \gdef\docm@iii#1\docm@iii{%
  85.  \ifx\next\docm@iii \let\next\next@ \docecho@ \let\next@\docm@
  86.  \else\ifx\next@\empty \let\next@\docfinish@
  87.  \else \edef\next@{\noexpand\docm@iv\next@/DOCMODE#1\noexpand\docm@iv}%
  88.  \fi\fi \next@}%
  89. \xywarnifdefined\docm@iv
  90.  \gdef\docm@iv#1/DOCMODE\docm@iv{\def\next{#1}\docecho@ \docm@}}%
  91.  
  92. \xywarnifdefined\docecho@ \global\let\docecho@\relax
  93. \xywarnifdefined\docfinish@ \gdef\docfinish@{\xyuncatcodes|DOCMODE\next}}
  94.  
  95. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  96.  
  97.     After giving an overview of the \XY-pic environment in \S??[env] we
  98.     document the basic concepts of \XY-picture construction in
  99.     \S??[basics], including the maintained `graphic state'.  The
  100.     following sections give the precise syntax rules of the main \XY-pic
  101.     constructions: the position language in~\S??[pos], the object
  102.     constructions in~\S??[object], and the picture `decorations'
  103.     in~\S??[decor].  \S??[objectlib] presents the kernel repertoire of
  104.     objects for use in pictures; \S??[option] documents the interface to
  105.     \XY-pic options like the standard `feature' and `extension' options.
  106.  
  107. \DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  108.  
  109.     Details of the implementation are not discussed in this \APPENDIX\ 
  110.     but in the complete \TeX\-nical documentation~\cite{R94:XY-picCSTC}.
  111.  
  112. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  113.  
  114.     Section \S??[algo] documents the more complicated algorithms used to
  115.     compute directions, edges, and connections.
  116.  
  117.     This \APPENDIX\ includes all of the text in the ``Basic
  118.     \XY-pictures'' reference manual~\cite{R94:XY-picRM}.
  119.  
  120. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  121.  
  122.  
  123. \subsection*{Notation}
  124.  
  125.     We will give descriptions of the "syntax" of pictures as \BNF??w[BNF]
  126.     rules; in explanations we will use upper case letters like $X$ and
  127.     $Y$ for <dimen>sions and lower case like $x$ and $y$ for <factor>s.
  128.  
  129. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  130.  
  131.  
  132.  
  133. \section{The \XY-pic implementation}
  134. ??=[env]
  135.  
  136.     This section briefly discusses the various aspects of the present
  137.     \XY-pic kernel implementation of which the user should be aware in
  138.     order to experiment with it.
  139.  
  140. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  141.  
  142.  
  143. \subsection{Loading \XY-pic}
  144. ??=[env.loading]??w[loading]
  145.  
  146.     \XY-pic is careful to set up its own environment in order to function
  147.     with a large variety of formats.  For most formats a single line with
  148.     the command
  149. $$
  150.  ??c![\input xy]
  151. $$
  152.     in the preamble of a document file should load the kernel (see
  153.     `integration with standard formats' below for variations possible
  154.     with certain formats, in particular \LaTeX~\cite{L94:LaTeX}).
  155.  
  156.     The rest of this section describes things you must consider if you
  157.     need to use \XY-pic together with other macro packages, style
  158.     options, or formats.  The less your environment deviates from plain
  159.     \TeX\ the easier it should be.
  160. \DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  161.     Consult the \TeX\-nical documentation~\cite{R94:XY-picCSTC} for the
  162.     exact requirements for other definitions to coexist with \XY-pic.
  163.  
  164. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  165.  
  166. \paragraph*{File header:}
  167. ??w[file header]
  168.  
  169.     Here is what actually happens in the header of |xy.doc|.  It contains
  170.     the copyright message, protection against ??w![loading] the file more
  171.     than once, and then bootstrap code to handle category codes and the
  172.     ??c![DOCMODE] format---we explain each separately below:
  173.  
  174. \DOCHEADER
  175.  
  176. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  177.  
  178. \paragraph*{Privacy:}
  179. ??w[privacy]
  180.  
  181.     \XY-pic will warn about control sequences it redefines---thus you can
  182.     be sure that there are no conflicts between \XY-pic-defined control
  183.     sequences, those of your format, and other macros, provided you
  184.     load??w[loading] \XY-pic last and get no ??w![warning
  185.     messages] like
  186. $$
  187.  |XY-pic Warning: `|\dots|' redefined.|??w[redefined]
  188. $$
  189.     In general the \XY-pic kernel will check all control sequences it
  190.     redefines "except" that (1)~generic temporaries like ??c![\next] are
  191.     not checked, (2)~predefined font identifiers (see~\S??[env.fonts])
  192.     are assumed intentionally preloaded, and (3)~some of the more exotic
  193.     control sequence names used internally (like |\dir{-}|) are only
  194.     checked to be different from ??c![\relax].
  195.  
  196. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  197.  
  198.     This is handled by ??c![\xywarnifdefined]---after we have ensured
  199.     that it is unique itself\footnote{This may seem paranoid but in fact
  200.     many inconvieniences in the \TeX\ world stem from the fact that
  201.     somebody copied somebody elses definition of, say,
  202.     {\tt\string\xywarnifdefined}, modified it, and then used it in
  203.     something that somehow got distributed!     The `flat name space'
  204.     problem remains \TeX\ largest problem as a programming language in
  205.     this \TeX\ hackers opinion.}.  ??c![\xydef@], ??c![\xylet@], and
  206.     |\xynew@{|<type>|}|??c[\xynew@] are abbreviations used to this end
  207.     throughout \XY-pic instead of ??c![\let], ??c![\def], and the
  208.     |\new|<type> commands.
  209.  
  210.     Next some auxilliaries: |\xydefcsname@| is similar to |\xydef@|
  211.     except that it builds the control sequence with ??c![\csname] \dots\
  212.     ??c![\endcsname] which means that it is |\relax| when undefined---there
  213.     is thus no way to prevent redefinition of control sequences bound to
  214.     ??c![\relax]~\frowny.
  215.  
  216. \DOCMODE(
  217. \xydef@\xydefcsname@#1{\DN@{#1}\DNii@##1{%
  218.   \ifx ##1\relax\else \xywarning@{`\string##1\string' redefined.}\fi \def##1}%
  219.  \expandafter\nextii@\csname\codeof\next@\endcsname}
  220. \DOCMODE)
  221.  
  222.     |\xyletcsnamecsname@| is to ??c![\let] one weird control sequence
  223.     be the same as another using several |\expandafter|s:
  224.  
  225. \DOCMODE(
  226. \xydef@\xyletcsnamecsname@#1#2{\def\1{#1}\def\2{#2}\DN@##1##2{%
  227.   \ifx ##1\relax\else \xywarning@{`\string##1\string' redefined.}\fi
  228.   \let##1=##2}%
  229.  \expandafter\expandafter\expandafter\next@
  230.   \expandafter\csname\expandafter\codeof\expandafter\1\expandafter\endcsname
  231.    \csname\codeof\2\endcsname}
  232. \DOCMODE)
  233.  
  234.     Finally ??c![\codeof]: a useful hack used to allow any characters in
  235.     control sequences: |\codeof|<cs> expands to the characters of the
  236.     control sequence <cs> as a string of `other' characters, \ie, all of
  237.     category 12 and with a \verb*/ /$_{12}$ after every control sequence.
  238.     <cs> must be a macro or it blows up.
  239.  
  240. \DOCMODE(
  241. \xywarnifdefined\codeof
  242. \xywarnifdefined\codeof@
  243. {\catcode`\:=12 \catcode`\>=12 % to ensure that all of :->< are other...
  244.  \gdef\codeof#1{\expandafter\codeof@\meaning#1<-:}
  245.  \gdef\codeof@#1:->#2<-:{#2}}
  246. \DOCMODE)
  247.  
  248.     Similarly ??c![\charof@]: returns the character with category 12; it
  249.     must have category 11 or 12 for this to work.  Useful when a
  250.     character is |\let| to some control sequence.
  251.  
  252. \DOCMODE(
  253. \xydef@\charof#1{\expandafter\c@arof@\meaning#1}
  254. \xywarnifdefined\charof@
  255. {\let\1=\gdef \let\2=\catcode \2`\t=12 \2`\h=12 \2`\e=12
  256.  \1\c@arof@ the #1 #2{#2}}
  257. \DOCMODE)
  258.  
  259.     \TODO: Actually the best would be to have a unique prefix, say |xy@|,
  260.     used for all private internal control sequences\dots
  261.  
  262. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  263.  
  264. \paragraph*{Category codes:}
  265.  
  266.     Unfortunately the situation is complicated by the flexibility of
  267.     \TeX's input format.  The culprit is the `??w![category code]'
  268.     concept of \TeX\ (\cf~\cite[p.37]{K84:TeXbook}): when loaded \XY-pic
  269.     requires the characters {\tt\char32}|\{}%| (the first is a space) to
  270.     have their standard meaning and all other printable characters to
  271.     have the "same category as when \XY-pic will be used"---in particular
  272.     this means that (1)~you should surround the ??w![loading] of \XY-pic
  273.     with ??c![\makeatother] \dots\ ??c![\makeatletter] when loading it
  274.     from within a \LaTeX\ package, and that (2)~\XY-pic should be loaded
  275.     after files that change category codes (like the |german.sty| that
  276.     makes |"| active??w[active characters]).
  277.  
  278. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  279.  
  280.     We define ??c![\xyuncatcodes] to restore the current catcodes, and
  281.     |\xycatcodes| to install our own.
  282.  
  283.     Here is an exact list of the category codes which \XY-pic requires
  284.     (all standard in plain \TeX):
  285. $$
  286. \vcenter{\tabskip=.5em plus1fil \halign to\displaywidth{#\hfil&&\hfil#\hfil\cr
  287.  character(s)  &|\| &|{| &|}| &CR &TAB SP&|A|--|Z| |a|--|z| &|0|--|9| &|%| \cr
  288.  category code & 0  & 1     & 2  & 5 & 10      & 11         & 12       & 14 \cr}
  289. }$$
  290.     Furthermore none of the remaining printable ASCII characters
  291. $$
  292.  |!"#$&'()*,/:;?@[]^_`||~|
  293. $$
  294.     may be of category 0, 1, 2, 9, 14, or 15, because all should be
  295.     tokens allowed in the replacement text of a |\def|---this also means
  296.     that they may not be active characters defined to be ``|\outer|''!
  297.  
  298.     All other catcodes needed are established using ??c![\xycatcodes]
  299.     defined above---this is the reason the macros must be loaded at a
  300.     time where the category codes are stable (otherwise it will make them
  301.     stable!).
  302.  
  303.     Internally \XY-pic enforces the following category codes:
  304. $$
  305. \vcenter{\tabskip=.5em plus1fil \halign to\displaywidth{#\hfil&&\hfil#\hfil\cr
  306.  character    &|#|&|$|&|&|&|'|&|+|&|-|&|.|&|<|&|=|&|>|&|@|&|`|\cr
  307.  ASCII code   & 35& 36& 38& 39& 43& 45& 46& 60& 61& 62& 64& 96\cr
  308.  category code& 6 & 3 & 4 & 12& 12& 12& 12& 12& 12& 12& 11& 12\cr
  309.  abbreviation&|HASH|&|DOLL|&|AND|&|RQ|&|PLUS|&|DASH|&|DOT|
  310.                           &|LT|&|EQ|&|GT|&|AT|&|LQ|\cr}
  311. }$$
  312.     with special control sequences named |\add|<abbreviation>|@| that
  313.     take an argument and expand to it followed by the original character
  314.     token, \ie, many tests throughout the program look like |\addDOT@|
  315.     |\ifx| |\next| \dots
  316.  
  317.     Here is the code to build the special |\add|\dots|@| control
  318.     sequences---this of course involves reestablishing the original
  319.     codes.
  320.  
  321. \DOCMODE(
  322. \xydef@\xymakeADD@#1#2 #3 {\ifnum\catcode#3=6 \xydef@#1##1{##1#2#2}%
  323.  \else\xydef@#1##1{##1#2}\fi}
  324.  
  325. \def\next{\xymakeADD@\addAT@}
  326. \xyuncatcodes
  327. \next @ 64 \catcode 64 11
  328.  
  329. \xymakeADD@\addHASH@    # 35
  330. \xymakeADD@\addDOLL@    $ 36
  331. \xymakeADD@\addAND@    & 38
  332. \xymakeADD@\addRQ@    ' 39
  333. \xymakeADD@\addPLUS@    + 43
  334. \xymakeADD@\addDASH@    - 45
  335. \xymakeADD@\addDOT@    . 46
  336. \xymakeADD@\addLT@    < 60
  337. \xymakeADD@\addEQ@    = 61
  338. \xymakeADD@\addGT@    > 62
  339. \xymakeADD@\addLQ@    ` 96
  340.  
  341. \xycatcodes
  342. \DOCMODE)
  343.  
  344.     The last block of the header bootstraps the ``??c![DOCMODE] format''
  345.     used in |.doc| variants of \XY-pic macro files in order to keep
  346.     documentation and macros together in a literal programming style
  347.     (this is redundant in the |xy.tex| macro file where all instances of
  348.     |DOCMODE| have been eliminated (see chapter \S??g[Makefile] for how
  349.     this is accomplished) but it is included anyway since users may load
  350.     options still in |DOCMODE| format).  The details of |DOCMODE| are
  351.     described in |xydoc.sty|, a special \LaTeX\ package used to typeset
  352.     \XY-pic documentation; please read it if you intend to write \XY-pic
  353.     options.
  354.  
  355. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  356.  
  357. \paragraph*{Integration with standard formats}
  358. ??w[formats]
  359.  
  360.     The ??w![integration] with various formats is handled by the
  361.     |xyidioms.tex| file and the integration as a \LaTeX~\cite{L94:LaTeX}
  362.     package by |xy.sty|:
  363.  
  364. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  365.  
  366.     We input |xyidioms.tex| from the kernel:
  367.  
  368. \DOCMODE(
  369. \input xyidioms
  370. \DOCMODE)
  371.  
  372. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  373.  
  374. \subparagraph{xyidioms.doc:}
  375. ??c[xyidioms.doc]
  376.  
  377. \inputdoc!{xyidioms.doc}
  378.  
  379. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  380.  
  381. \subparagraph{xy.sty:}
  382. ??c[xy.sty]
  383. %
  384.     If you use ??w![\LaTeX] then this file makes it possible to
  385.     load??w[loading] \XY-pic as a `??w![package]' using the
  386.     \LaTeXe~\cite{L94:LaTeX} |\usepackage| command:
  387. %
  388. \begin{defs1}
  389. |\usepackage| |[|<option>|,|\dots|]| |{xy}|
  390. \end{defs1}
  391. \noindent\unskip
  392. %
  393.     where the <option>s will be interpreted as if passed to |\xyoption|
  394.     (\cf~\S??[option]); furthermore options that require special
  395.     activation will also be activated when loaded this way (\eg,
  396.     including |cmtip| in the <option> list will not only perform
  397.     |\xyoption| |{cmtip}| but also |\Use|\-|Computer|\-|Modern|\-|Tips|).
  398.  
  399.     Driver package options (\cf~\cite[table 11.2, p.317]{GMS94:LaTeXC})
  400.     will invoke the appropriate backend (\cf~\S??g[:ps]).
  401.  
  402.     The file also works as a \LaTeX~2.09~\cite{L86:LaTeX} `??w![style
  403.     option]' although you will have to load options with the \XY-pic
  404.     mechanism.
  405.  
  406. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  407.  
  408.     Here is the raw source of |xy.sty|.
  409.  
  410. \inputdoc0{xy.sty}
  411.  
  412. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  413.  
  414.  
  415. \subsection{Logo, version, and messages}
  416. ??=[env.logo]
  417.  
  418.     Loading \XY-pic prints a ??w![banner] containing the version and
  419.     author of the kernel; small progress ??w![messages] are printed when
  420.     each major division of the kernel has been loaded.  Any options
  421.     loaded will announce themself in a similar fashion.
  422.  
  423. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  424.  
  425.     Of these, |\stripRCS| is a very useful hack for extracting the first
  426.     component of an RCS |$|\dots|$| keyword value.
  427.  
  428. \DOCMODE(
  429. \xydef@\stripRCS$#1${\stripRCS@#1: @@ @@@}
  430. \xydef@\stripRCS@#1: #2@ #3@@@{%
  431.  \ifx @#2\string?\else\ifx :#2\else\stripRCS@@#2\fi\fi}
  432. \xydef@\stripRCS@@#1 #2: @{#1}
  433.  \edef\next{\stripRCS$Revision: 2.12 $}
  434.  \edef\next@{\stripRCS$Locker:  $}
  435. \xylet@\xyversion=\next
  436.  \def\next{ @}\ifx\next\next@\else \edef\xyversion{\xyversion.\next@}\fi
  437.  \edef\next{\stripRCS$Date: 1994/10/25 11:55:12 $}
  438. \xylet@\xydate=\next
  439.  \def\next{ @}\ifx\next\next@\else\edef\xydate{\xydate\space(work version)}\fi
  440.  
  441. \xydef@\XYgreet@{%
  442.  \W@{}%
  443.  \W@{ XY-pic version \xyversion\space<\xydate>}%
  444.  \W@{ Copyright (c) 1991-1994 by Kristoffer H. Rose <kris@diku.dk>}%
  445.  \W@{ XY-pic is free software: see the User\string's Guide for details.}%
  446.  \W@{}}
  447. \XYgreet@
  448. \expandafter\everyjob\expandafter{\the\everyjob\XYgreet@}
  449.  
  450. \message{Loading kernel:}
  451. \DOCMODE)
  452.  
  453. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  454.  
  455.     If you refer to \XY-pic in your written text (please do~\smiley~)
  456.     then you can use the command ??c![\Xy]|-pic| to typeset the
  457.     ``??w![\XY-pic]'' ??w![logo].  The ??w![version] of the kernel is
  458.     typeset by |\xyversion| and the release date by |\xydate| (as found
  459.     in the banner).  By the way, the \XY-pic "name"\footnote{No
  460.     description of a \TeX\ program is complete without an explanation of
  461.     its name.}  originates from the fact that the first version was
  462.     little more than support for $(x,y)$ coordinates in a configurable
  463.     coordinate system where the main idea was that "all" operations could
  464.     be specified in a manner independent of the orientation of the
  465.     coordinates.  This property has been maintained except that now the
  466.     package allows explicit absolute orientation as well.
  467.  
  468. \DOCMODE(
  469. \xydef@\XY{\leavevmode
  470.  \hbox{\kern-.1em X\kern-.3em\lower.4ex\hbox{Y\kern-.15em}}}
  471.  
  472. \xylet@\Xy=\XY
  473. \DOCMODE)
  474.  
  475. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  476.  
  477.     Messages that start with ``|XY-pic| ??c![Warning]'' are indications
  478.     that something needs your attention; an ``|XY-pic| ??c![Error]'' will
  479.     stop \TeX\ because \XY-pic does not know how to proceed.
  480.  
  481. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  482.  
  483.     We use the input line number if available and rudimentary help in the
  484.     form of a reference to the manual if no specific help string is
  485.     given.  ??c![\newlinechar] is set locally to |^^J| while writing such
  486.     that messages of several lines can be written.
  487.  
  488. \DOCMODE(
  489. \message{messages;}
  490.  
  491. \xywarnifdefined\thelineno@
  492. \ifx\inputlineno\undefined \edef\thelineno@{\string?}
  493. \else \def\thelineno@{\the\inputlineno}\fi
  494. \xydef@\xytracelineno@{ \string[\jobname:\thelineno@\string]}
  495.  
  496. \xydef@\xywarning@#1{{\newlinechar=`\^^J%
  497.   \W@{}\W@{XY-pic Warning: #1\xytracelineno@.}\W@{}}}
  498.  
  499. \xydef@\xyerror@#1#2{{\DNii@{#2}\newlinechar=`\^^J%
  500.   \ifx\nextii@\empty \errhelp{See the XY-pic manual for further information.}%
  501.   \else \errhelp{#2}\fi
  502.   \errmessage{XY-pic error: #1}}}
  503. \DOCMODE)
  504.  
  505.     Finally one that I hope will never get expanded~\frowny
  506.  
  507. \DOCMODE(
  508. \xydef@\xybug@#1{{\newlinechar=`\^^J%
  509.  \errhelp{This is a bug in XY-pic and should not happen!^^J%
  510. If it did then please send a bug report with the offending XY-pic code^^J%
  511. to the author of XY-pic, kris@diku.dk.}%
  512.  \errmessage{XY-pic BUG: #1 -- notify kris@diku.dk.}}}
  513. \DOCMODE)
  514.  
  515. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  516.  
  517.  
  518. \subsection{Fonts}
  519. ??=[env.fonts]
  520.  
  521.     The \XY-pic kernel implementation makes its drawings using five
  522.     specially designed ??w![fonts]:%
  523. %
  524. ??w[dashes]??w[tips]??w[circles]??w[hooks]??w[squiggles]
  525. $$
  526. \begin{array}{\otherbar c\otherbar c\otherbar l\otherbar}
  527. \hline
  528.  \hbox{Font}    & \hbox{Characters}            & \hbox{Default}\\
  529. \hline                                    
  530.  ??c![\xydashfont]& \hbox{dashes}            & ??c![xydash10]\\
  531.  ??c![\xyatipfont]& \hbox{arrow tips, upper half}    & ??c![xyatip10]\\
  532.  ??c![\xybtipfont]& \hbox{arrow tips, lower half}    & ??c![xybtip10]\\
  533.  ??c![\xybsqlfont]& \hbox{quarter circles for\qquad}    & ??c![xybsql10]\\
  534.         & \hbox{\qquad hooks and squiggles}    &\\
  535.  ??c![\xycircfont]& \hbox{$1/8$ circle segments}    & ??c![xycirc10]\\
  536. \hline
  537. \end{array}
  538. $$
  539.     The first four contain variations of characters in a large number of
  540.     directions, the last contains 1/8 circle segments.
  541.  
  542. \paragraph*{Note:}
  543.     The default fonts are not part of the \XY-pic kernel "specification":
  544.     they just set a standard for what drawing capabilities should at
  545.     least be required by an \XY-pic implementation.  Implementations
  546.     exploiting capabilitites of particular output devices are in use.
  547.     Hence the fonts are only loaded by \XY-pic if the control sequence
  548.     names are undefined---this is used to preload them at different sizes
  549.     or prevent them from being loaded at all.
  550.  
  551. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  552.  
  553.     To be more precise, \XY-pic requires ??c![\xydashfont] to be a
  554.     "??w![semidirectional]" font as \MF\ will generate with the driver
  555.     file ??c![xyd2.mf]---this is very important because the "??w![italic
  556.     corrections]" of the characters in this particular font are used to
  557.     approximate trigonometric computations, so if you replace
  558.     |\xydashfont| be sure to replace it with another semidirectional
  559.     font!  Similarly, the three fonts |\xyatipfont|, |\xybtipfont|, and
  560.     |\xybsqlfont| should be "??w![directional]" as \MF\ will generate
  561.     with the driver file ??c![xyd.mf].
  562.  
  563.     Finally, |\xycircfont| should contain $1/8$ circle segments of
  564.     various radii as described in |xycirc10.mf|.
  565.  
  566.     The following code loads the fonts "unless it was already loaded" and
  567.     defines some associated dimensions for |\xydashfont| and
  568.     |\xybsqlfont|: for each of these $f$ we define $f_\ell$ as the length
  569.     of a unit in the current direction (used when juxtaposing for
  570.     connections), $f_h$ as the height of the unit (used for several
  571.     parallel connections), and $f_w$ as the `line width' of the unit (to
  572.     know how to interface to rules).
  573.  
  574. \DOCMODE(
  575. \message{fonts;}
  576.  
  577. \xydef@\xyfont@#1{\ifx#1\undefined \DN@{\global\font#1}\expandafter\next@
  578.  \else \xywarning@{Using previously loaded \string#1\space font.}\fi}
  579.  
  580. \xyfont@\xydashfont=xydash10
  581. \xydef@\xydashl@{\fontdimen6\xydashfont}
  582. \xydef@\xydashh@{\fontdimen5\xydashfont}
  583. \xydef@\xydashw@{\fontdimen8\xydashfont}
  584.  
  585. \xyfont@\xyatipfont=xyatip10
  586. \xyfont@\xybtipfont=xybtip10
  587.  
  588. \xyfont@\xybsqlfont=xybsql10
  589. \xydef@\xybsqll@{\fontdimen6\xybsqlfont}
  590. \xydef@\xybsqlh@{\fontdimen5\xybsqlfont}
  591. \xydef@\xybsqlw@{\fontdimen8\xybsqlfont}
  592.  
  593. \xyfont@\xycircfont=xycirc10
  594. \DOCMODE)
  595.  
  596. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  597.  
  598.  
  599. \subsection{Allocations}
  600. ??=[env.alloc]??w[allocation]
  601.  
  602.     One final thing that you must be aware of is the fact that \XY-pic
  603.     allocates a significant number of dimension registers and some
  604.     counters, token registers, and box registers, in order to represent
  605.     the state and do computations.  The \XY-pic v.\xyversion\ kernel
  606.     allocates 6~counters, 27~dimensions, 2~box registers, 3~token
  607.     registers, 1~read channel, and 1~write channel (when running under
  608.     plain \TeX; under \LaTeX\ and \AMS-\TeX\ slightly less is allocated
  609.     because the provided temporaries are used).  Options may allocate
  610.     further registers.
  611.  
  612. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  613.  
  614. \DOCMODE(
  615. \message{allocations:}
  616. \DOCMODE)
  617.  
  618.     See \S??[env.loading] for scratch register allocations.
  619.  
  620. \paragraph*{Picture state:}
  621.  
  622.     These realise the picture state as described in \S??[basics.state]:
  623.     $c$, $p$, the "base", and the picture size:
  624.  
  625. \DOCMODE(
  626. \message{state,}
  627.  
  628. \xynew@{dimen}\Xc
  629. \xynew@{dimen}\Yc
  630. \xynew@{dimen}\Uc
  631. \xynew@{dimen}\Dc
  632. \xynew@{dimen}\Lc
  633. \xynew@{dimen}\Rc
  634. \xynew@{toks}\Edgec
  635.  
  636. \xynew@{dimen}\Xp
  637. \xynew@{dimen}\Yp
  638. \xynew@{dimen}\Up
  639. \xynew@{dimen}\Dp
  640. \xynew@{dimen}\Lp
  641. \xynew@{dimen}\Rp
  642. \xynew@{toks}\Edgep
  643.  
  644. \xynew@{dimen}\Xorigin \Xorigin=\z@
  645. \xynew@{dimen}\Yorigin \Xorigin=\z@
  646. \xynew@{dimen}\Xxbase  \Xxbase=1mm
  647. \xynew@{dimen}\Yxbase  \Yxbase=\z@
  648. \xynew@{dimen}\Xybase  \Xybase=\z@
  649. \xynew@{dimen}\Yybase  \Yybase=1mm
  650.  
  651. \xynew@{dimen}\Xmin
  652. \xynew@{dimen}\Ymin
  653. \xynew@{dimen}\Xmax
  654. \xynew@{dimen}\Ymax
  655. \DOCMODE)
  656.  
  657. \paragraph*{Drop and connect:}
  658.  
  659.     |\lastobjectbox@| stores the most recently dropped
  660.     object.??c[\lastobject]
  661.  
  662. \DOCMODE(
  663. \xynew@{box}\lastobjectbox@
  664. \DOCMODE)
  665.  
  666.     |\zerodotbox@|??c[\zerodot] is of zero size with a `dot' in the form
  667.     of a rule the width and height as the line width of the line font.
  668.  
  669. \DOCMODE(
  670. \xynew@{box}\zerodotbox@
  671. \setbox\zerodotbox@=\hbox{\dimen@=.5\xydashw@
  672.  \kern-\dimen@ \vrule width\xydashw@ height\dimen@ depth\dimen@}
  673. \wd\zerodotbox@=\z@ \ht\zerodotbox@=\z@ \dp\zerodotbox@=\z@
  674. \DOCMODE)
  675.  
  676. \paragraph*{Direction state:}
  677.  
  678.     The ??w![direction] state is rather complicated and described in
  679.     detail in~\S??[algo.direction].
  680.  
  681. \DOCMODE(
  682. \message{direction,}
  683.  
  684. \xynew@{dimen}\dX
  685. \xynew@{dimen}\dY
  686. \xydef@\sdX{}
  687. \xydef@\sdY{}
  688.  
  689. \xynew@{count}\K \K=1024
  690. \xynew@{count}\KK@ \KK@=32
  691.  
  692. \xynew@{count}\Direction
  693. \xynew@{dimen}\K@dXdY
  694. \xynew@{dimen}\K@dYdX
  695.  
  696. \xydef@\cosDirection{}
  697. \xydef@\sinDirection{}
  698.  
  699. \xywarnifdefined\DirectionChar
  700. \xywarnifdefined\SemiDirectionChar
  701. \DOCMODE)
  702.  
  703. \paragraph*{Miscellaneous:}
  704.  
  705.     Finally some generic allocations used in the following:
  706.  
  707. \DOCMODE(
  708. \xynew@{read}\xyread@            % for `safe input'
  709. \xynew@{write}\xywrite@            % for `saving' to .xyc file
  710.  
  711. \xynew@{count}\csp@            % for `control stack pointer'
  712. \xynew@{dimen}\quotPTK@            % for `fractions'
  713. \DOCMODE)
  714.  
  715.     The required temporaries are defined by |xyidioms.tex|.
  716.  
  717. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  718.  
  719.  
  720. \subsection{Utility macros}
  721. ??=[env.util]
  722.  
  723.     Finally we define some utility macros.
  724.  
  725. \DOCMODE(
  726. \message{utility macros;}
  727. \DOCMODE)
  728.  
  729. \paragraph*{Simple queue:}
  730. ??w[queue]
  731.  
  732.     Just appending and prepending to the ??c![\toks@] list.
  733.  
  734. \DOCMODE(
  735. \xydef@\addtotoks@#1{\toks@=\expandafter{\the\toks@#1}}
  736.  
  737. \xydef@\prependtotoks@#1{%
  738.  \expandafter\def\expandafter\prependtotoks@@\expandafter{\the\toks@}%
  739.  \toks@=\expandafter\expandafter\expandafter{%
  740.    \expandafter\prependtotoks@@\the\toks@}}
  741.  
  742. \xylet@\prependtotoks@@=\relax
  743. \DOCMODE)
  744.  
  745. \paragraph*{Safe input:}
  746.  
  747.     Check that file is available before input.
  748.  
  749. \DOCMODE(
  750. \xydef@\xyinputorelse@#1#2{\openin\xyread@=#1 %
  751.  \ifeof\xyread@ \DN@{#2}\else \DN@{\closein\xyread@\input#1 }\fi \next@}
  752. \DOCMODE)
  753.  
  754. \paragraph*{Continuation stack:}
  755.  
  756.     This is used to `??w![enter]' a new ??w![context] and `??w![leave]'
  757.     to the previous context.  It works as a stack defining a control
  758.     sequence for each level, thus using a counter as the stack pointer.
  759.     Defines the following
  760. %
  761. \begin{defs}
  762.  |\csp@| & `Continuation Stack Pointer' \cr
  763.  |\enter@{|<code>|}| & Enter new block with <code> expanded as continuation\cr
  764.  |\nter@{|<code>|}| & Enter new block with<code> as continuation\cr
  765.  |\dontleave@| & Execute continuation without leaving block\cr
  766.  |\unenter@| & Leave block without executing its continuation\cr
  767.  |\leave@| & Leave block (execute its continuation)\cr
  768. \end{defs}
  769.  
  770.     So |\enter@{}\leave@| is a noop and |\leave@| is the same as
  771.     |\dontleave@\unenter@|.
  772.  
  773. \DOCMODE(
  774. \global\csp@=\z@
  775.  
  776. \xydef@\enter@#1{\global\advance\csp@\@ne
  777.  \expandafter\xdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
  778.  
  779. \xydef@\nter@#1{\global\advance\csp@\@ne
  780.  \expandafter\gdef\csname cs@\number\csp@\endcsname{#1}\ignorespaces}
  781.  
  782. \xydef@\dontleave@{\csname cs@\number\csp@\endcsname}
  783.  
  784. \xydef@\unenter@{\global\advance\csp@\m@ne}
  785.  
  786. \xydef@\leave@{\expandafter\unenter@\csname cs@\number\csp@\endcsname}
  787. \DOCMODE)
  788.  
  789. \paragraph*{Fractions:}
  790. ??w[fraction computation]
  791.  
  792.     Below we often use a factor on the form of a quotient $A/B$.  Here is
  793.     a hack to get it; it is not very precise but suffices for our needs.
  794. %
  795. \begin{defs}
  796.  |\quotient@| <cs> |{|$A$|}| |{|$B$|}| &
  797.     Defines <cs> to expand (immediately) to the factor corresponding to
  798.     $A/B$; $A$, $B$ must be dimensions where $\abs{A}\lt|\maxdimen|/|KK|$
  799.     and $\abs{B}\gt|KK|$
  800. \cr
  801.  |\quotient@@| <cs> |{|$A$|}| |{|$B$|}| &
  802.     Same, but uses $8|KK|$ for |KK|.
  803. \cr
  804. \end{defs}
  805. %
  806.     "Notes": (1) If |\c| is a count register, then |{1\c}| is a legal
  807.     dimension. (2) Really computes
  808. $$
  809.  \left((A*\abs{|KK|}) / (B/\abs{|KK|})\right) * \left(|1pt|/\abs{|K|}\right)
  810. $$
  811.     and then defines <cs> to expand to the resulting |pt| value.  This
  812.     means that results are only reasonable for
  813.     $\abs{A}\ll|\maxdimen|/|KK|$ and $\abs{B}\gg|KK|$.
  814.  
  815. \DOCMODE(
  816. \quotPTK@=\p@ \divide\quotPTK@\K
  817. \xylet@\quotsign@@=\empty
  818. \xywarnifdefined\removePT@
  819. {\catcode`p=12 \catcode`t=12 \gdef\removePT@#1pt{#1}}
  820.  
  821. \xydef@\quotient@#1#2#3{\A@=#2\relax \B@=#3\relax
  822.  \ifdim\A@<\z@\def\quotsign@@{-}\else\def\quotsign@@{+}\fi
  823.  \ifdim\quotsign@@\A@<15pt \multiply\A@\K
  824.  \else\ifdim\quotsign@@\A@<511pt \multiply\A@\KK@ \divide\B@\KK@
  825.  \else \divide\B@\K \fi\fi
  826.  \ifdim\ifdim\B@<\z@-\fi\B@<\quotPTK@ \xywarning@{division overflow}%
  827.  \else \advance\A@.5\B@ \divide\A@\B@ \fi
  828.  \multiply\A@\quotPTK@ \edef#1{\expandafter\removePT@\the\A@}}
  829.  
  830. \xydef@\quotient@@#1#2#3{\A@=#2\relax \B@=#3\relax
  831.  \multiply\A@\KK@ \divide\B@\KK@ \divide\B@ 8 %
  832.  \ifdim\B@=\z@\else \advance\A@.5\B@ \divide\A@\B@ \fi
  833.  \B@=.125\quotPTK@ \multiply\A@\B@ \edef#1{\expandafter\removePT@\the\A@}}
  834. \DOCMODE)
  835.  
  836. \paragraph*{Loops:}
  837.  
  838.     \XY-pic uses its own |\loop@| to avoid interference with plain
  839.     ??c![\loop].
  840.  
  841. \DOCMODE(
  842. \xydef@\loop@#1\repeat@{\def\body@{#1}\iterate@}\xylet@\repeat@=\fi
  843. \xydef@\iterate@{\body@\expandafter\iterate@\else\fi}
  844. \DOCMODE)
  845.  
  846. \paragraph*{Execution:}
  847.  
  848.     All ??w![execution] of \XY-commands should be `indirect', \ie,
  849.     execute
  850. $$
  851.  |\xy@{|<source>|}{|<internal commands>|}|
  852. $$
  853.     where the <internal commands> directly do the desired operation(s).
  854.     This is used for tracing and can be used to separate parsing and
  855.     execution by changing |\xy@|; |\oxy@| is kept stable such that
  856.     |\let\xy@=\oxy@| will reestablish a sane state.
  857.  
  858. \DOCMODE(
  859. \xydef@\xyinitial@#1#2{\DN@{#1}%
  860.  \xyerror@{XY-pic command used out of context: \codeof\next@}{}}
  861.  
  862. \xylet@\xy@=\xyinitial@
  863. \xylet@\oxy@=\xy@
  864. \DOCMODE)
  865.  
  866.     This is also used to check whether an \XY-picture is already
  867.     active; use as |\if\inxy@|\dots|\else|\dots|\fi|:
  868.  
  869. \DOCMODE(
  870. \xydef@\inxy@{T\ifx\xy@\xyinitial@ F\else T\fi}
  871. \DOCMODE)
  872.  
  873.     The final execution command is a trick used to put bits of the user's
  874.     input inside the |\next@| scratch macro "with the user's catcodes
  875.     intact": |\xy@@ix@{|\dots|}| is the same as
  876.     |\xy@@{\global\toks9={|\dots|}}| except for the category codes used
  877.     for the \dots.
  878.  
  879. \DOCMODE(
  880. \xydef@\xyxy@@ix@{\begingroup
  881.  \xyuncatcodes\afterassignment\endgroup\global\toks9=}
  882. \DOCMODE)
  883.  
  884.     This to save some tokens -- maybe not worth it:
  885.  
  886. \DOCMODE(
  887. \xydef@\xy@@{\xy@{}}
  888. \DOCMODE)
  889.  
  890.     Finally this to establish a sane state -- only use within a group!
  891.  
  892. \DOCMODE(
  893. \xydef@\plainxy@{\let\xy@=\xyxy@ \let\oxy@=\xy@ \let\xy@@ix@=\xyxy@@ix@}
  894. \DOCMODE)
  895.  
  896.     \TODO: Clean up all uses of these such that <source> is always that
  897.     and only that.  Define a method for `inner' \aka\ `implied' <source>
  898.     that doesn't really count in that it is a consequence of some other
  899.     source\dots
  900.  
  901. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  902.  
  903.  
  904.  
  905. \section{Picture basics}
  906. ??=[basics]
  907.  
  908.     The basic concepts involved when constructing \XY-pictures are
  909.     positions and objects, and how they constitute a state used by the
  910.     graphic engine.
  911.  
  912.     The general structure of an \XY-picture is as follows:
  913. %
  914. \begin{defs1}
  915. %
  916.   ??c![\xy] <pos> <decor> ??c![\endxy] \cr
  917. %
  918. \end{defs1}
  919. \noindent\unskip
  920. %
  921.     builds a box with an \XY-picture (\LaTeX\ users may substitute
  922.     |\begin{xy}| \dots\ |\end{xy}| if they prefer).  <pos> and <decor>
  923.     are components of the special `graphic language' which \XY-pictures
  924.     are specified in.  We explain the language components in general
  925.     terms in this \S\ and in more depth in the following \S\S.
  926.  
  927. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  928.  
  929.     The code for the |\xy|\dots|\endxy| command is presented last in this
  930.     section.
  931.  
  932. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  933.  
  934.  
  935. \subsection{Positions}
  936. ??=[basics.pos]
  937.  
  938.     All "??w![positions]" may be written |<|$X$|,|$Y$|>| where ??w![$X$]
  939.     is the \TeX\ dimension distance "right" and ??w![$Y$] the distance
  940.     "up" from the "??w![zero position]" ??c![0] of the \XY-picture (|0|
  941.     has coordinates |<0mm,0mm>|, of course).  The zero position of the
  942.     \XY-picture determines the box produced by the |\xy|\dots|\endxy|
  943.     command together with the four parameters ??w![$X_{\min}$],
  944.     ??w![$X_{\max}$], ??w![$Y_{\min}$], and ??w![$Y_{\max}$] set such
  945.     that all the objects in the picture are `contained' in the following
  946.     rectangle:
  947. $$
  948. \xy.(-13,-12).(25,15)="b"*\frm{-}*\dir{o},
  949.  "b"+<2pc,-.8pc>*{|0|};"b"*{}**\dir{.},
  950.  "b"+L+<-2pc,-.8pc>*!UR\txt{\TeX\ reference point};"b"+L*\dir{*}**\dir{.},
  951.  "b"+0;
  952.  "b"+L **\dir{-} ?>*\dir{>} ?*++!U{X_{\min}},
  953.  "b"+R **\dir{-} ?>*\dir{>} ?(.7)*++!U{X_{\max}},
  954.  "b"+D **\dir{-} ?>*\dir{>} ?(.7)*++!L{Y_{\min}},
  955.  "b"+U **\dir{-} ?>*\dir{>} ?*++!L{Y_{\max}}
  956. \endxy
  957. $$
  958.     where the distances follow the ``up and right~$\gt0$'' principle,
  959.     \eg, the indicated \TeX\ reference point has coordinates
  960.     |<|$X_{\min}$|,0pt>| within the \XY-picture.  The zero position does
  961.     not have to be contained in the picture, but $X_{\min} \le X_{\max}
  962.     \land Y_{\min} \le Y_{\max}$ always holds.  The possible positions
  963.     are described in detail in~\S??[pos].
  964.  
  965. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  966.  
  967.  
  968. \subsection{Objects}
  969. ??=[basics.object]
  970.  
  971.     The simplest form of putting things into the picture is to `drop' an
  972.     "??w![object]" at a position.  An object is like a \TeX\ box except
  973.     that it has a general "??w![Edge]" around its reference point---in
  974.     particular this has the "??w![extents]" (\ie, it is always contained
  975.     within) the dimensions ??w![$L$], ??w![$R$], ??w![$U$], and ??w![$D$]
  976.     away from the reference point in each of the four directions left,
  977.     right, up, and down.  Objects are encoded in \TeX\ boxes using the
  978.     convention that the ??w![\TeX\ reference point] of an object is at
  979.     its left edge, thus shifted |<|${-}L$|,0pt>| from the center---so a
  980.     \TeX\ box may be said to be a rectangular object with $L=|0pt|$.
  981.     Here is an example:
  982. $$
  983.  \let\objectstyle=\scriptstyle
  984.  \xy(0,0).(-10,-5).(15,8)*\frm{-}="box"*\dir{o}+0;
  985.   "box"+L*{}**\dir{.}?*{L},
  986.   "box"+R*{}**\dir{.}?*{R},
  987.   "box"+D*{}**\dir{.}?*{D},
  988.   "box"+U*{}**\dir{.}?*{U},
  989.   "box"+L+<-2pc,-.8pc>*!UR\hbox{\TeX\ reference point};
  990.    "box"+L*{\bullet}*{}**\dir{.},
  991.  \endxy
  992. $$
  993.     The object shown has a rectangle edge but others are available even
  994.     though the kernel only supports rectangle and circle edges.  It is
  995.     also possible to use entire \XY-pictures as objects with a rectangle
  996.     edge, |0| as the reference point, $L={-X_{\min}}$, $R={X_{\max}}$,
  997.     $D={-Y_{\min}}$, and $U={Y_{\max}}$.  The commands for objects are
  998.     described in~\S??[object].
  999.  
  1000. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1001.  
  1002.  
  1003. \subsection{Connections}
  1004. ??=[basics.connect]
  1005.  
  1006.     Besides having the ability to be dropped at a position in a picture,
  1007.     all objects may be used to "??w![connect]" the two current objects of
  1008.     the state, \ie, $p$ and $c$.  For most objects this is done by
  1009.     `filling' the straight line between the centers with as many copies
  1010.     as will fit between the objects:
  1011. $$
  1012.  \let\objectstyle=\scriptscriptstyle
  1013.  \xy*=<12pt>[o]{p}="P"*\cir{} ; (60,15)*=<18pt,8pt>{c}="C"*\frm{-}**\dir{--}
  1014. %
  1015.   **\xybox{(0,0).(-3,-2).(2,3)*\frm{.}="box"*\dir{o}+0;
  1016.    "box"+L**\dir{.}?*{L},
  1017.    "box"+R**\dir{.}?*{R},
  1018.    "box"+D**\dir{.}?*{D},
  1019.    "box"+U**\dir{.}?*{U}},
  1020.  \endxy
  1021. $$
  1022.     The ways the various objects connect are described along with the
  1023.     objects.
  1024.  
  1025. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1026.  
  1027.  
  1028. \subsection{Decorations}
  1029. ??=[basics.decor]
  1030.  
  1031.     When the ??c![\xy] command reaches something that can not be
  1032.     interpreted as a continuation of the position being read, then it is
  1033.     expected to be a "??w![decoration]", \ie, in a restricted set of
  1034.     \TeX\ commands which add to pictures.  Most such commands are
  1035.     provided by the various "user options" (\cf~\S??[option])---only a
  1036.     few are provided within the kernel to facilitate programming of such
  1037.     options (and user macros) as described in~\S??[decor].
  1038.  
  1039. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1040.  
  1041.  
  1042. \subsection{The \XY-pic state}
  1043. ??=[basics.state]
  1044.  
  1045.     Finally we summarise the user-accessible parts of the
  1046.     ??w![\XY-picture state] of two positions together with the
  1047.     last object associated with each: the "previous", ??w![$p$], is the
  1048.     position |<|??w![$X_p$]|,| ??w![$Y_p$]|>| with the object
  1049.     ??w![$L_p$], ??w![$R_p$], ??w![$D_p$], ??w![$U_p$], ??w![$"Edge"_p$],
  1050.     and the "current", ??w![$c$], is the position |<|??w![$X_c$]|,|
  1051.     ??w![$Y_c$]|>| with the object ??w![$L_c$], ??w![$R_c$], ??w![$D_c$],
  1052.     ??w![$U_c$], ??w![$"Edge"_c$].
  1053.  
  1054.     Furthermore, \XY-pic has a configurable "??w![cartesian coordinate
  1055.     system]" described by an "origin" position |<|??w![$X_"origin"$]|,|
  1056.     ??w![$Y_"origin"$]|>| and two "base vectors" |<|??w![$X_"xbase"$]|,|
  1057.     ??w![$Y_"xbase"$]|>| and~|<|??w![$X_"ybase"$]|,|
  1058.     ??w![$Y_"ybase"$]|>|, and accessed by the usual notation using
  1059.     parenthesis:
  1060. $$
  1061. \arraycolsep=.25em \begin{array}{rclll}
  1062.  |(|x|,|y|)| & = & |<| & X_"origin" + x*X_"xbase" + y*X_"ybase" & |,| \\
  1063.          &     &     & Y_"origin" + x*Y_"xbase" + y*Y_"ybase" & |>| \\
  1064. \end{array}
  1065. $$
  1066.     This is explained in full when we show how to set the base in
  1067.     note~??[base] of \S??[pos].
  1068.  
  1069.     Finally typesetting a connection will setup a ``??w![placement
  1070.     state]'' for referring to positions on the connection that is
  1071.     accessed through a special |?| position construction; this is also
  1072.     discussed in detail in \S??[pos].
  1073.  
  1074.     The \XY-pic "??w![state]" consists of all these parameters
  1075.     together. They are initialised to zero except for
  1076.     $X_"xbase"=Y_"ybase"=|1mm|$.  The dimension parameters are directly
  1077.     available as \TeX\ |\dimen| registers with the obvious names:
  1078.     ??c![\Xmin], ??c![\Xmax], ??c![\Ymin], and ??c![\Ymax]; ??c![\Xp],
  1079.     ??c![\Yp] ??c![\Dp], ??c![\Up], ??c![\Lp], and ??c![\Rp]; ??c![\Xc],
  1080.     ??c![\Yc] ??c![\Dc], ??c![\Uc], ??c![\Lc], and ??c![\Rc];
  1081.     ??c![\Xorigin], ??c![\Yorigin], ??c![\Xxbase], ??c![\Yxbase],
  1082.     ??c![\Xybase], and ??c![\Yybase].
  1083.  
  1084. \DOCMODE1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1085.     The edges are not directly available (but see the technical
  1086.     documentation for how to access them).
  1087.  
  1088. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1089.     The edges are are available to the programmer as token lists; see
  1090.     \S??[algo.edge] for details.
  1091.  
  1092. \subparagraph*{Procedure:}
  1093.  
  1094.     ??c![\xy]\ \dots\ ??c![\endxy] builds an object from an \XY-pic <pos>
  1095.     <decor> sequence as follows: (??_[xy1])~|\xy| starts the |\hbox| to
  1096.     contain the \XY-picture, (??_[xy2])~starts an inner box to be resized
  1097.     appropriately later, sets |\xy@| to just execute immediately, and
  1098.     makes a fresh scope for global internal names, and
  1099.     (??_[xy3])~initialises the \XY-pic state (setting the size to a
  1100.     ridiculously large negative value) and passes control to the <pos>
  1101.     parser.
  1102.  
  1103. \DOCMODE(
  1104. \message{pictures: \string\xy,}
  1105.  
  1106. \xydef@\xy{\hbox\bgroup \aftergroup\xycheck@end            %?*[xy1]
  1107.  \setboxz@h\bgroup                        %?*[xy2]
  1108.   \plainxy@
  1109.   \Xc=\z@ \Yc=\z@ \czeroEdge@                    %?*[xy3]
  1110.   \Xp=\z@ \Yp=\z@ \Up=\z@ \Dp=\z@ \Lp=\z@ \Rp=\z@ \Edgep={\zeroEdge}%
  1111.   \Xmin=\hsize \Xmax=-\hsize \Ymin=\hsize \Ymax=-\hsize
  1112.   \POS}
  1113.  
  1114. \xydef@\czeroEdge@{\Uc=\z@ \Dc=\Uc \Lc=\Uc \Rc=\Uc \Edgec={\zeroEdge}}
  1115.  
  1116. \xydef@\xyxy@#1#2{#2}
  1117. \DOCMODE)
  1118.  
  1119.     When finished |\endxy| does a |\relax| to disable any parser still
  1120.     active and (??_[endxy1])~resets the size of the generated box to zero
  1121.     if no (unhidden) objects were inserted, and (??_[endxy2])~defines a
  1122.     command to end both the temporary and the `proper' box and set its
  1123.     size correctly---this uses ??c![\edef] to expand the required
  1124.     dimensions used within the temporary box before leaving the two
  1125.     groups (namely the temporary box and the `proper' box).
  1126.  
  1127. \DOCMODE(
  1128. \xydef@\endxy{\relax
  1129.   \dimen@=\Ymax \advance\dimen@-\Ymin                %?*[endxy1]
  1130.   \ifdim\dimen@<\z@ \dimen@=\z@ \Ymin=\z@ \Ymax=\z@ \fi
  1131.   \dimen@=\Xmax \advance\dimen@-\Xmin
  1132.   \ifdim\dimen@<\z@ \dimen@=\z@ \Xmin=\z@ \Xmax=\z@ \fi
  1133.   \edef\tmp@{\egroup                        %?*[endxy2]
  1134.     \setboxz@h{\kern-\the\Xmin\boxz@}%
  1135.     \ht\z@=\the\Ymax \dp\z@=-\the\Ymin \wdz@=\the\dimen@ \boxz@
  1136.     \egroup \noexpand\xy@end
  1137.     \Uc=\the\Ymax \Dc=-\the\Ymin \Lc=-\the\Xmin \Rc=\the\Xmax}\tmp@}
  1138. \DOCMODE)
  1139.  
  1140.     If an |\xy| is not properly closed by an |\endxy| then the error
  1141.     message is produced. This happens if (a)~too many |\xy|s or (b)~too
  1142.     many |\endxy|s or (c)~if there is the correct number of each but the
  1143.     grouping becomes unbalanced due to a misplaced |}| or |\egroup|.
  1144.  
  1145. \DOCMODE(
  1146. \xydef@\xycheck@end{\xyFN@\xycheck@end@}
  1147. \xydef@\xycheck@end@{\ifx\next\xy@end\DN@\xy@end{}\else\DN@{\xy@end}\fi\next@}
  1148. \xydef@\xy@end{%
  1149.  \xyerror@{An \string\xy\space environment is not closed correctly.}%
  1150.   {I expected \string\endxy.  You probably have an umatched {} grouping.}}
  1151. \DOCMODE)
  1152.  
  1153. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1154.  
  1155.  
  1156.  
  1157. \section{Positions}
  1158. ??=[pos]
  1159.  
  1160. \DOCMODE(
  1161. \message{positions,}
  1162. \DOCMODE)
  1163.  
  1164.     A <pos>ition is a way of specifying locations as well as dropping
  1165.     objects at them and decorating them---in fact any aspect of the
  1166.     \XY-pic state can be changed by a <pos> but most will just change the
  1167.     coordinates and/or shape of~$c$.
  1168.  
  1169. \begin{figure*}[tp]
  1170. \vss
  1171. \begin{syntax}
  1172.  ??w![<pos>]
  1173.   &\iss    & <coord>
  1174.     & $c\from<coord>$
  1175. \cr
  1176.   &\orr    & <pos> ??c![+] <coord>
  1177.     & $c \from <pos> + <coord>$??^[arithmetic]
  1178. \cr
  1179.   &\orr    & <pos> ??c![-] <coord>
  1180.     & $c \from <pos> - <coord>$??^[arithmetic]
  1181. \cr
  1182.   &\orr    & <pos> ??c![!] <coord>
  1183.     & $c\from<pos>$ then ??!^[skew] $c$ by <coord>
  1184. \cr
  1185.   &\orr    & <pos> ??c![.] <coord>
  1186.     & $c\from<pos>$ but also ??!^[covering] $<coord>$
  1187. \cr
  1188.   &\orr    & <pos> ??c![,] <coord>
  1189.     & $c\from<pos>$ then $c\from<coord>$
  1190. \cr
  1191.   &\orr    & <pos> ??c![;] <coord>
  1192.     & $c\from<pos>$, swap $p$ and $c$, $c\from<coord>$
  1193. \cr
  1194.   &\orr    & <pos> ??c![:] <coord>
  1195.     & $c\from<pos>$, set ??!^[base], $c\from<coord>$
  1196. \cr
  1197.   &\orr    & <pos> ??c![::] <coord>
  1198.     & $c\from<pos>$, $"ybase"\from c-"origin"$, $c\from<coord>$
  1199. \cr
  1200.   &\orr    & <pos> ??c![*] <object>
  1201.     & $c\from<pos>$, ??!^[drop] <object>
  1202. \cr
  1203.   &\orr    & <pos> ??c![**] <object>
  1204.     & $c\from<pos>$, ??!^[connect] using <object>
  1205. \cr
  1206.   &\orr    & <pos> ??c![?] <place>
  1207.     & $c\from<pos>$, $c\from\hbox{??!^[<place>]}$
  1208. \cr
  1209.   &\orr    & <pos> <stacking>
  1210.     & $c\from<pos>$, do <stacking>
  1211. \cr
  1212.   &\orr    & <pos> <saving>
  1213.     & $c\from<pos>$, do <saving>
  1214. \cr
  1215. \noalign{\smallbreak}
  1216. %
  1217.  ??w![<coord>]
  1218.   &\iss    & <vector>
  1219.     & <pos> is <vector> with zero size
  1220. \cr
  1221.   &\orr    & <empty> \orr\ ??c![c]
  1222.     & reuse last $c$ (do nothing)
  1223. \cr
  1224.   &\orr    & ??c![p]
  1225.     & $p$
  1226. \cr
  1227.   &\orr    & ??c![x] \orr\ ??c![y]
  1228.     & ??!^[axis intersection] with $\overline{pc}$
  1229. \cr
  1230.   &\orr    & ??c![s]<digit> \orr\ |s{|<number>|}|
  1231.     & ??!^[stack] position <digit> or <number> below the top
  1232. \cr
  1233.   &\orr    & |"|<id>|"|
  1234.     & restore what was ??!^[saved] as <id> earlier
  1235. \cr
  1236.   &\orr    & |{| <pos> <decor> |}|
  1237.     & the $c$ resulting from interpreting the ??!^[group]
  1238. \cr
  1239. \noalign{\smallbreak}
  1240. %
  1241.  ??w![<vector>]
  1242.   &\iss    & ??c![0]
  1243.     & zero
  1244. \cr
  1245.   &\orr    & |<| <dimen> |,| <dimen> |>|
  1246.     & absolute??c[<>]
  1247. \cr
  1248.   &\orr    & |<| <dimen> |>|
  1249.     & absolute with equal dimensions
  1250. \cr
  1251.   &\orr    & |(| <factor> |,| <factor> |)|
  1252.     & in current ??!^[base]??c[()]
  1253. \cr
  1254.   &\orr    & ??c![a] |(| <number> |)|
  1255.     & ??!^[angle in current base]
  1256. \cr
  1257.   &\orr    & <corner>
  1258.     & from reference point to <corner> of $c$
  1259. \cr
  1260.   &\orr    & <corner> |(| <factor> |)|
  1261.     & The <corner> multiplied with <factor>
  1262. \cr
  1263.   &\orr    & |/| <direction> <dimen> |/|
  1264.     & vector <dimen> ??!^[in <direction>]??c[//]
  1265. \cr
  1266. \noalign{\smallbreak}
  1267. %
  1268.  ??w![<corner>]
  1269.   &\iss    & ??c![L]\orr??c![R]\orr??c![D]\orr??c![U]
  1270.     & ??!^[offset] to left, right, down, up side
  1271. \cr
  1272.   &\orr    & ??c![CL]\orr??c![CR]\orr??c![CD]\orr??c![CU]\orr??c![C]
  1273.     & ??!^[offset] to center of side, true center
  1274. \cr
  1275.   &\orr    & ??c![LD]\orr??c![RD]\orr??c![LU]\orr??c![RU]
  1276.     & ??!^[offset] to actual left/down, \dots\ corner
  1277. \cr
  1278.   &\orr    & ??c![E]\orr??c![P]
  1279.     & ??!^[offset] to nearest/proportional edge point to $p$
  1280. \cr
  1281. \noalign{\smallbreak}
  1282. %
  1283.  ??w![<place>]
  1284.   &\iss    & ??c![<] <place>
  1285.     & ??!^[shave] ??c![(0)] to edge of $p$, $f \from |0|$
  1286. \cr
  1287.   &\orr    & ??c![>] <place>
  1288.     & ??!^[shave] ??c![(1)] to edge of $c$, $f \from |1|$
  1289. \cr
  1290.   &\orr    & |(| <factor> |)| <place>
  1291.     & $f \from <factor>$
  1292. \cr
  1293.   &\orr    & <slide>
  1294.     & ??!^[pick place] and apply <slide>
  1295. \cr
  1296. \noalign{\smallbreak}
  1297. %
  1298.  ??w![<slide>]
  1299.   &\iss    & |/| <dimen> |/|
  1300.     & ??!^[slide] <dimen> further along connection
  1301. \cr
  1302.   &\orr    & <empty>
  1303.     & no slide
  1304. \cr
  1305. \noalign{\smallbreak}
  1306. %
  1307.  ??w![<stacking>]
  1308.   &\iss    & ??c![@i] \orr\ ??c![@(] \orr\ ??c![@)]
  1309.     & init, enter, leave ??!^[stack]
  1310. \cr
  1311.   &\orr    & ??c![@+] <coord> \orr\ ??c![@-] <coord>
  1312.     & push $<coord>$;  $c\from<coord>$ and pop (on ??!^[stack])
  1313. \cr
  1314.   &\orr    & ??c![@@] <coord>
  1315.     & do $<coord>$ ??!^[for every stack element]
  1316. \cr
  1317. \noalign{\smallbreak}
  1318. %
  1319.  ??w![<saving>]
  1320.   &\iss    & ??c![=] |"|<id>|"|
  1321.     & ??!^[save] $c$ as |"|<id>|"|
  1322. \cr
  1323.   &\orr    & |=|<code> |"|<id>|"|
  1324.     & ??!^[define macro] |"|<id>|"|
  1325. \cr
  1326. \end{syntax}
  1327. \unskip\vskip-1em
  1328. \caption{\protect<pos>itions.}??=[f.pos]
  1329. \vfill
  1330. \end{figure*}
  1331.  
  1332.     All possible positions are shown in figure~??[f.pos] with explanatory
  1333.     notes below.
  1334.  
  1335. \begin{exercise}
  1336.     Which of the positions |0|, |<0pt,0pt>|, |<0pt>|, |(0,0)|, and
  1337.     |/0pt/| is different from the others?
  1338. \answertext{In the default setup they are all denote the reference point of
  1339.     the \XY-picture but the cartesian coordinate <pos> ??c![(0,0)]
  1340.     denotes the point "origo" that may be changed to something else using
  1341.     the |:| operator.}
  1342. \end{exercise}
  1343.  
  1344. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1345.  
  1346. \paragraph*{Parsing:}
  1347.  
  1348.     First the ??c![\POS] and ??c![\afterPOS] <decor>ations, and similar
  1349.     ??c![\afterCOORD] and ??c![\afterVECTORorEMPTY] ones.  They handle
  1350.     parsing of <pos>, <coord>, and <vector>; parsing of <corner> and
  1351.     <place> is presented along with note~??[corner] and~??[<place>]
  1352.     explaining them.
  1353.  
  1354. \DOCMODE(
  1355. \xydef@\POS{\afterPOS{}}
  1356.  
  1357. \xydef@\afterPOS#1{%
  1358.  \DN@##1{\def\afterPOS@{\def\afterPOS@{##1}#1}}%
  1359.  \expandafter\next@\expandafter{\afterPOS@}%
  1360.  \afterCOORD{\xyFN@\POS@}}
  1361.  
  1362. \xylet@\afterPOS@=\empty
  1363.  
  1364. \xydef@\afterCOORD#1{%
  1365.  \DN@##1{\def\afterCOORD@{\def\afterCOORD@{##1}#1}}%
  1366.  \expandafter\next@\expandafter{\afterCOORD@}%
  1367.  \afterVECTORorEMPTY{\xy@@\czeroEdge@ \afterCOORD@}{\xyFN@\COORD@}}
  1368.  
  1369. \xylet@\afterCOORD@=\empty
  1370.  
  1371. \xydef@\afterVECTORorEMPTY#1#2{%
  1372.  \DN@##1{\def\afterVECTOR@{\def\afterVECTOR@{##1}%
  1373.   \ifVECTORempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
  1374.  \expandafter\next@\expandafter{\afterVECTOR@}%
  1375.  \xyFN@\VECTOR@}
  1376.  
  1377. \xynew@{if}\ifVECTORempty@
  1378. \xylet@\afterVECTOR@=\empty
  1379. \DOCMODE)
  1380.  
  1381.     The ??c![\afterVECTORorEMPTY] command is special in that it takes two
  1382.     arguments: the `continuation' if a <vector> was found and the
  1383.     continuation if <empty> was found (this is not applicable to the
  1384.     other two since <empty> is a legal <coord> and thus also a legal
  1385.     <pos>).
  1386.  
  1387.     Next we proceed with the actual parsing primitives: |\COORD@|,
  1388.     |\POS@|, and |\VECTOR@|.  These are bound to |\xyCOORD@|, |\xyPOS@|,
  1389.     and |\xyVECTOR@| in order to be extendable, \eg, the |matrix| option
  1390.     extends <coord> to support the |[|"row"|,| "column"|]| format by
  1391.     redefining |\COORD@| to first test for this new format and then call
  1392.     |\xyCOORD@|.
  1393.  
  1394.     The parsing commands above are set up such that they all first call
  1395.     the |\VECTOR@| command.  <coord> and <pos> parsing then proceeds with
  1396.     calling the |\COORD@| if there was no <vector>.  <pos> parsing then
  1397.     calls |\POS@| to continue the <pos> (in both cases).
  1398.  
  1399.     First <vector>s:
  1400.  
  1401. \DOCMODE(
  1402. \xydef@\xyVECTOR@{%
  1403.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\VECTOR@}%gobble spaces
  1404.  \else \ifcat A\noexpand\next \let\next@=\VECTOR@letter
  1405.  \else \let\next@=\VECTOR@other \fi\fi \next@}
  1406.  
  1407. \xylet@\VECTOR@=\xyVECTOR@
  1408. \DOCMODE)
  1409.  
  1410.     All letters used for <vector>s are uppercase <corner>s except for |a|
  1411.     used for angles (where the main code is in note~??[angle in current
  1412.     base]):
  1413.  
  1414. \DOCMODE(
  1415. \xydef@\VECTOR@letter{%
  1416.  \ifx a\next \expandafter\VECTOR@a \else \expandafter\CORNER@ \fi}
  1417.  
  1418. \xydef@\VECTOR@a a(#1){\xy@{a(#1)}{\vfromcartesianangle@{#1}}%
  1419.  \VECTORempty@false \afterVECTOR@}
  1420. \DOCMODE)
  1421.  
  1422.     The <corner> trick is to do nothing when there is nothing and
  1423.     initialise both $X$ and $Y$ in all other cases.
  1424.  
  1425. \DOCMODE(
  1426. \xydef@\CORNER@{%
  1427.  \xy@{}{\A@=-.5\Lc \advance\A@.5\Rc \B@=-.5\Dc \advance\B@.5\Uc
  1428.   \let\nextii@=\zeroit@}%
  1429.  \VECTORempty@true\CORNER@i}
  1430.  
  1431. \xydef@\zeroit@#1{#1=\z@}
  1432.  
  1433. \xydef@\CORNER@i{%
  1434.  \ifx D\next      \DN@ D{\xy@{D}{\Yc=-\Dc \nextii@\Xc \B@=\Yc}\CORNER@ii}%
  1435.  \else\ifx U\next \DN@ U{\xy@{U}{\Yc= \Uc \nextii@\Xc \B@=\Yc}\CORNER@ii}%
  1436.  \else\ifx L\next \DN@ L{\xy@{L}{\Xc=-\Lc \nextii@\Yc \A@=\Xc}\CORNER@ii}%
  1437.  \else\ifx R\next \DN@ R{\xy@{R}{\Xc= \Rc \nextii@\Yc \A@=\Xc}\CORNER@ii}%
  1438.  \else\ifx C\next \DN@ C{\xy@{C}{\Xc= \A@ \Yc= \B@}\CORNER@ii}%
  1439.  \else\ifx E\next \DN@ E{\xy@{E}{%
  1440.     \A@=\Xc \B@=\Yc \the\Edgec\z@ \advance\Xc-\A@ \advance\Yc-\B@}\CORNER@ii}%
  1441.  \else\ifx P\next \DN@ P{\xy@{P}{%
  1442.     \A@=\Xc \B@=\Yc \the\Edgec\thr@@ \advance\Xc-\A@ \advance\Yc-\B@}%
  1443.    \CORNER@ii}%
  1444.  \else\ifx (\next %)
  1445.    \DN@(##1){\xy@{(##1)}{\Xc=##1\Xc \Yc=##1\Yc}\afterVECTOR@}%
  1446.  \else \let\next@=\afterVECTOR@
  1447.  \fi\fi\fi\fi\fi\fi\fi\fi \next@}
  1448.  
  1449. \xydef@\CORNER@ii{\xy@@{\let\nextii@=\eat@}%
  1450.  \VECTORempty@false \xyFN@\CORNER@i}
  1451. \DOCMODE)
  1452.  
  1453.     |\CORNER@i| recognises the |(|<factor>|)| also; this does no harm as
  1454.     it was never called if the first character was a |(|.
  1455.  
  1456.     The remaining <vector> forms just set $X$ and $Y$:
  1457.  
  1458. \DOCMODE(
  1459. \xydef@\VECTOR@other{%
  1460.  \addLT@\ifx \next
  1461.   \addGT@{\addLT@\DN@##1}{%
  1462.    \xy@{<##1>}{\vfromabsolute@{##1}}\VECTORempty@false\afterVECTOR@}%
  1463.  \else\ifx (\next %)
  1464.   \DN@(##1){%
  1465.    \xy@{(##1)}{\vfromcartesian@{##1}}\VECTORempty@false\afterVECTOR@}%
  1466.  \else\ifx /\next %/
  1467.   \DN@/##1/{\xy@{/##1/}{\vfromslide@{##1}}%
  1468.    \VECTORempty@false\afterVECTOR@}%
  1469.  \else\ifx 0\next
  1470.   \DN@ 0{\xy@{0}{\Xc=\z@ \Yc=\z@}\VECTORempty@false\afterVECTOR@}%
  1471.  \else
  1472.   \DN@{\VECTORempty@true\afterVECTOR@}%
  1473.  \fi\fi\fi\fi \next@}
  1474. \DOCMODE)
  1475.  
  1476.     Next <coord>inates that are not <vector>s:
  1477.  
  1478. \DOCMODE(
  1479. \xydef@\xyCOORD@{%
  1480.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\COORD@}%gobble spaces
  1481.  \else \ifcat A\noexpand\next \let\next@=\xyCOORD@letter
  1482.  \else \let\next@=\xyCOORD@other \fi\fi \next@}
  1483.  
  1484. \xylet@\COORD@=\xyCOORD@
  1485.  
  1486. \xydef@\xyCOORD@letter{%
  1487.  \ifx c\next
  1488.   \DN@ c{\xy@{c}{}\afterCOORD@}%
  1489.  \else\ifx p\next
  1490.   \DN@ p{\xy@{p}\cfromp@ \afterCOORD@}%
  1491.  \else\ifx x\next
  1492.   \DN@ x{\xy@{x}{\Rc=\Xxbase \Uc=\Yxbase \intersect@}\afterCOORD@}%
  1493.  \else\ifx y\next
  1494.   \DN@ y{\xy@{y}{\Rc=\Xybase \Uc=\Yybase \intersect@}\afterCOORD@}%
  1495.  \else\ifx s\next
  1496.   \DN@ s##1{\xy@{s{##1}}{\cfroms@{##1}}\afterCOORD@}%
  1497.  \else \let\next@=\afterCOORD@ \fi\fi\fi\fi\fi \next@}
  1498.  
  1499. \xydef@\xyCOORD@other{%
  1500.  \ifx "\next %"
  1501.   \DN@"##1"{\xy@{"##1"}{\cfromid@{##1}}\afterCOORD@}%
  1502.  \else\ifx \bgroup\next
  1503.   \DN@##1{\xy@{{##1}}{\enter@{\pfromthep@\basefromthebase@}}%
  1504.    \POS##1\relax \xy@@\leave@ \afterCOORD@}%
  1505.  \else \let\next@=\afterCOORD@ \fi\fi \next@}
  1506. \DOCMODE)
  1507.  
  1508.     Finally <pos> parsing after <coord> (possibly <vector>) is
  1509.     interpreted:
  1510.  
  1511. \DOCMODE(
  1512. \xydef@\xyPOS@{%
  1513.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\POS@}%gobble spaces
  1514.  \else\addPLUS@\ifx \next
  1515.   \addPLUS@\DN@{\xy@+{\enter@\cplusthec@}%
  1516.     \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
  1517.  \else\addDASH@\ifx \next
  1518.   \addDASH@\DN@{\xy@-{\enter@\cplusthec@}%
  1519.     \afterCOORD{\xy@@{\Xc=-\Xc \Yc=-\Yc\leave@}\xyFN@\POS@}}%
  1520.  \else\ifx !\next
  1521.   \DN@ !{\xy@!{\enter@\cskewthec@}\afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
  1522.  \else\addDOT@\ifx \next
  1523.   \addDOT@\DN@{\xy@.{\enter@\cmergethec@}%
  1524.    \afterCOORD{\xy@@\leave@ \xyFN@\POS@}}%
  1525.  \else\ifx ,\next
  1526.   \DN@ ,{\xy@,{}\afterCOORD{\xyFN@\POS@}}%
  1527.  \else\ifx ;\next
  1528.   \DN@ ;{\xy@;{\swap@}\afterCOORD{\xyFN@\POS@}}%
  1529.  \else\ifx :\next
  1530.   \DN@ :{\xyFN@\oneortwocolons@}%
  1531.  \else\addEQ@\ifx \next
  1532.   \addEQ@\DN@{\xyFN@\saveid@}%
  1533.  \else\ifx *\next
  1534.   \DN@ *{\xyFN@\oneortwostars@}%
  1535.  \else \ifx ?\next
  1536.   \DN@?{\xy@?{}\afterPLACE{\xyFN@\POS@}}%
  1537.  \else \addAT@\ifx \next
  1538.   \addAT@\DN@{\xyFN@\STACK@}%
  1539.  \else
  1540.   \let\next@=\afterPOS@
  1541.  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
  1542.  
  1543. \xylet@\POS@=\xyPOS@
  1544. \DOCMODE)
  1545.  
  1546.     The final functions serve only to distinguish between the single
  1547.     character |:|/|*| and dual character |::|/|**| operators:
  1548.  
  1549. \DOCMODE(
  1550. \xydef@\oneortwocolons@{\DNii@{\afterCOORD{\xyFN@\POS@}}%
  1551.  \ifx :\next \xy@{::}{\setbase@@\Xc\Yc}\DN@:{\nextii@}%
  1552.  \else \xy@:{\setbase@\Xp\Yp\Xc\Yc}\let\next@=\nextii@ \fi
  1553.  \next@}
  1554.  
  1555. \xydef@\oneortwostars@{%
  1556.  \ifx *\next
  1557.   \DN@*##1##{\nextii@{##1}}%
  1558.   \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
  1559.    \xy@{**##1{##2}}{\expandafter\connect@\the\toks9}\xyFN@\POS@}%
  1560.  \else
  1561.   \DN@##1##{\nextii@{##1}}%
  1562.   \DNii@##1##2{\xy@@ix@{{##1}{##2}}%
  1563.    \xy@{*##1{##2}}{\expandafter\drop@\the\toks9}\xyFN@\POS@}%
  1564.  \fi
  1565.  \next@}
  1566. \DOCMODE)
  1567.  
  1568. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1569.  
  1570. \paragraph*{Simple actions:}
  1571.  
  1572.     Next follow the simplest actions; the complicated ones are explained
  1573.     along with their notes below.
  1574.  
  1575. \DOCMODE(
  1576. \xydef@\cfromp@{\Xc=\Xp \Yc=\Yp \Uc=\Up \Dc=\Dp \Lc=\Lp \Rc=\Rp
  1577.  \Edgec=\expandafter{\the\Edgep}}
  1578.  
  1579. \xydef@\pfromc@{\Xp=\Xc \Yp=\Yc \Up=\Uc \Dp=\Dc \Lp=\Lc \Rp=\Rc
  1580.  \Edgep=\expandafter{\the\Edgec}}
  1581.  
  1582. \xydef@\swapdimen@#1#2{\dimen@=#1\relax #1=#2\relax #2=\dimen@}
  1583.  
  1584. \xydef@\swap@{\swapdimen@\Xc\Xp \swapdimen@\Yc\Yp
  1585.  \swapdimen@\Uc\Up \swapdimen@\Dc\Dp \swapdimen@\Lc\Lp \swapdimen@\Rc\Rp
  1586.  \toks@=\Edgec \Edgec=\Edgep \Edgep=\toks@}
  1587. \DOCMODE)
  1588.  
  1589.     Next the parsing of coordinate pairs in |<>|:
  1590.  
  1591. \DOCMODE(
  1592. \xydef@\vfromabsolute@#1{\vfromabsolute@@#1,@}
  1593.  
  1594. \xydef@\vfromabsolute@@#1,#2@{\Xc=#1\relax
  1595.  \DN@{#2}\ifx\next@\empty \Yc=\Xc
  1596.  \else \DN@##1,{\Yc=##1}\next@#2\relax \fi}
  1597. \DOCMODE)
  1598.  
  1599.     The next group of commands are used to store on the control stack
  1600.     with the |\enter@| command, so they "expand" to something useful:
  1601.  
  1602. \DOCMODE(
  1603. \xydef@\cfromthec@{\Xc=\the\Xc \Yc=\the\Yc
  1604.  \Uc=\the\Uc \Dc=\the\Dc \Lc=\the\Lc \Rc=\the\Rc
  1605.  \Edgec={\expandafter\noexpand\the\Edgec}}
  1606.  
  1607. \xydef@\cfromthep@{\Xc=\the\Xp \Yc=\the\Yp
  1608.  \Uc=\the\Up \Dc=\the\Dp \Lc=\the\Lp \Rc=\the\Rp
  1609.  \Edgec={\expandafter\noexpand\the\Edgep}}
  1610.  
  1611. \xydef@\pfromthep@{\Xp=\the\Xp \Yp=\the\Yp
  1612.  \Up=\the\Up \Dp=\the\Dp \Lp=\the\Lp \Rp=\the\Rp
  1613.  \Edgep={\expandafter\noexpand\the\Edgep}}
  1614.  
  1615. \xydef@\pfromthec@{\Xp=\the\Xc \Yp=\the\Yc
  1616.  \Up=\the\Uc \Dp=\the\Dc \Lp=\the\Lc \Rp=\the\Rc
  1617.  \Edgep={\expandafter\noexpand\the\Edgec}}
  1618. \DOCMODE)
  1619.  
  1620. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1621.  
  1622. \begin{notes}
  1623.  
  1624. \note??=[arithmetic]
  1625. %
  1626.     When doing arithmetic with |+| and |-| then the resulting object
  1627.     inherits the size of the <coord>, \ie, the right argument---this will
  1628.     be zero if the <coord> is a <vector>.
  1629.  
  1630. \begin{exercise}
  1631.     How do you set $c$ to an object the same size as the saved object
  1632.     |"ob"| but moved |<|$X$|,|$Y$|>|?
  1633. \answertext{Use the <pos>ition |<|$X$|,|$Y$|>+"ob"|.}
  1634. \end{exercise}
  1635.  
  1636. \DOCMODE(
  1637. \xydef@\cplusthec@{\advance\Xc\the\Xc \advance\Yc\the\Yc}
  1638. \DOCMODE)
  1639.  
  1640. \note??=[skew]
  1641. %
  1642.     "Skewing" using |!| just means that the reference point of $c$ is
  1643.     moved with as little change to the shape of the object as possible,
  1644.     \ie, the edge of~$c$ will remain in the same location except that it
  1645.     will grow larger to avoid moving the reference point outside~$c$.
  1646. %
  1647. \begin{exercise}
  1648.     What does the <pos> \dots|!R-L| do?
  1649. \answertext{It first sets $c$ according to ``\dots''.  Then it changes $c$ to
  1650.     the point right of $c$ at the same distance from the right edge of
  1651.     $c$ as its width, $w$, \ie,
  1652. $$
  1653. \xy
  1654.  *+\hbox{The \dots}="it" *\frm{_\}}!D-U*{w}
  1655.  ,{"it"+RD}.{"it"+RU}.{"it"!R-L*{\times}+0}!C *\frm{_\}}!D-U*{w}
  1656. \endxy
  1657. $$}
  1658. \end{exercise}
  1659. %
  1660.     \BUG: The result of |!| is always a rectangle currently.
  1661.  
  1662. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1663.  
  1664. \paragraph*{Procedure:}
  1665.  
  1666.     |!| moves the center of $c$ by a temporarily read $c'$ and then
  1667.     readjusts the extents:
  1668. $$
  1669. \begin{array}{rclcl}
  1670.  D_c &:=& Y'+Y_c - \min(Y'-D', Y'+Y_c)      &=& \max(Y_c+D',0)\\
  1671.  U_c &:=& \max(Y'+U', Y'+Y_c) - (Y'+Y_c)  &=& \max(U'-Y_c,0)\\
  1672.  Y_c &:=& Y'+Y_c\\
  1673.  L_c &:=& X'+X_c - \min(X'-L', X'+X_c)      &=& \max(X_c+L',0)\\
  1674.  R_c &:=& \max(X'+R', X'+X_c) - (X'+X_c)  &=& \max(R'-X_c,0)\\
  1675.  X_c &:=& X'+X_c\\
  1676. \end{array}
  1677. $$
  1678.  
  1679. \DOCMODE(
  1680. \xydef@\cskewthec@{%
  1681.  \noexpand\cskew@{\the\Yc}{\the\Xc}{\the\Dc}{\the\Uc}{\the\Lc}{\the\Rc}}
  1682.  
  1683. \xydef@\cskew@#1#2#3#4#5#6{%
  1684.  \Dc=#3\advance\Dc \Yc \ifdim\Dc<\z@ \Dc=\z@ \fi
  1685.  \Uc=#4\advance\Uc-\Yc \ifdim\Uc<\z@ \Uc=\z@ \fi
  1686.  \advance\Yc#1%
  1687.  \Lc=#5\advance\Lc \Xc \ifdim\Lc<\z@ \Lc=\z@ \fi
  1688.  \Rc=#6\advance\Rc-\Xc \ifdim\Rc<\z@ \Rc=\z@ \fi
  1689.  \advance\Xc#2%
  1690.  \Edgec={\rectangleEdge}}
  1691. \DOCMODE)
  1692.  
  1693. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1694.  
  1695. \note??=[covering]
  1696. %
  1697.     A <pos> "covers" another if it is a rectangle with size sufficiently
  1698.     large that the other is ``underneath''.  The |.| operation
  1699.     ``extends'' a <pos> to cover an additional one---the reference point
  1700.     of $c$ is not moved but the shape is changed to a rectangle such that
  1701.     the entire $p$ object is covered.
  1702.  
  1703.     \NOTE: non-rectangular objects are first ``translated'' into a
  1704.     rectangle by using a diagonal through the object as the diagonal of
  1705.     the rectangle.
  1706.  
  1707. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1708.  
  1709. \paragraph*{Procedure:}
  1710.  
  1711.     |.| takes a temporary object $c'$ and adjusts the extents of $c$ such
  1712.     that it is covered.
  1713. $$
  1714. \begin{array}{rclcl}
  1715.  L_c &:=& X' - \min(X'-L_c, X-L) &=& \max(L_c,    A+L)\\
  1716.  R_c &:=& \max(X'+R_c, X+R) - X' &=& \max(R_c, -A+R)\\
  1717.  D_c &:=& Y' - \min(Y'-D_c, Y-D) &=& \max(D_c,    B+D)\\
  1718.  U_c &:=& \max(Y'+U_c, Y+U) - Y' &=& \max(U_c, -B+U)\\
  1719. \end{array}
  1720. $$
  1721.     with $|<|A|,|B|>| = |<|X'-X|,|Y'-Y|>|$.  First method~2 of the object
  1722.     is used to convert it into a rectangle.
  1723.  
  1724. \DOCMODE(
  1725. \xydef@\cmergethec@{%
  1726.  \noexpand\cmerge@{\the\Yc}{\the\Xc}{\the\Dc}{\the\Uc}{\the\Lc}{\the\Rc}}
  1727.  
  1728. \xydef@\cmerge@#1#2#3#4#5#6{\the\Edgec4%
  1729.  \A@=#2\advance\A@-\Xc \B@=#1\advance\B@-\Yc
  1730.  \dimen@=#5\advance\Lc \A@ \ifdim\Lc<\dimen@ \Lc=\dimen@ \fi
  1731.  \dimen@=#6\advance\Rc-\A@ \ifdim\Rc<\dimen@ \Rc=\dimen@ \fi
  1732.  \dimen@=#3\advance\Dc \B@ \ifdim\Dc<\dimen@ \Dc=\dimen@ \fi
  1733.  \dimen@=#4\advance\Uc-\B@ \ifdim\Uc<\dimen@ \Uc=\dimen@ \fi
  1734.  \advance\Xc\A@ \advance\Yc\B@}
  1735. \DOCMODE)
  1736.  
  1737. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1738.  
  1739. \note??=[base]
  1740. %
  1741.     The operations |:| and |::| set the "base" used for <coord>inates on
  1742.     the form $|(|x|,|y|)|$.  The |:| operation will set
  1743.     |<|$X_"origin"$|,| $Y_"origin"$|>| to~$p$, |<|$X_"xbase"$|,|
  1744.     $Y_"xbase"$|>| to $c-"origin"$, and~|<|$X_"ybase"$|,| $Y_"ybase"$|>|
  1745.     to |<|${-}Y_"xbase"$|,| $X_"xbase"$|>| (this ensures that it is a
  1746.     usual square coordinate system).  The |::| operation may then be used
  1747.     afterwards to make nonsqare bases by just setting "ybase" to
  1748.     $c-"origin"$.  Here are two examples |0;<1cm,0cm>:| will set the
  1749.     coordinate system
  1750. $$
  1751. \xy
  1752.  <0cm,0cm>*\dir{o};<1cm,0cm>:
  1753.  (0,0);{(1,0)**\dir{-}?>*\dir{>}},{(0,1)**\dir{-}?>*\dir{>}},
  1754.  (0,0)*+!UR\hbox{\small"origin"},
  1755.  (1,0)*+!LC\hbox{\small"xbase"},
  1756.  (0,1)*!D\hbox{\small"ybase"},
  1757.  (1,1)*{*}*++!CL{|(1,1)|}+0;(0,1)**\dir{.},(1,0)**\dir{.}
  1758. \endxy
  1759. $$
  1760.     and |<1cm,.5cm>;| |<2cm,1.5cm>:| |<1cm,1cm>::| will define
  1761. $$
  1762. \xy
  1763.  <0cm,0cm>*\dir{o}, <1cm,.5cm>;<2cm,1.5cm>:
  1764. %
  1765.  (0,0);{(0,1)**\dir{--}?(1)*\dir{>}},
  1766.  (0,1)*+!R\txt\small{"ybase"\\before\\{\tt::}},
  1767. %
  1768.  <1cm,1cm>::
  1769.  (0,0);{(1,0)**\dir{-}?(1)*\dir{>}},{(0,1)**\dir{-}?(1)*\dir{>}},
  1770.  (0,0)*+!LU\txt\small{"origin"},
  1771.  (1,0)*+!LC\txt\small{"xbase"},
  1772.  (0,1)*!D\txt\small{"ybase"},
  1773.  (1,1)*{*}*++!CL{|(1,1)|}+0;(0,1)**\dir{.},(1,0)**\dir{.}
  1774. \endxy
  1775. $$
  1776.     where in each case the $\circ$ is at |0|, the base vectors have been
  1777.     drawn, and the $\times$ is at |(1,1)|.
  1778.  
  1779.     When working with vectors these two special <factor>s are
  1780.     particularly useful:
  1781. %
  1782. \begin{defs}
  1783.  |\halfroottwo| & $0.70710678\approx\sqrt2/2$ \cr
  1784.  |\halfrootthree| & $0.86602540\approx\sqrt3/2$ \cr
  1785. \end{defs}
  1786.  
  1787. \DOCMODE(
  1788. \xydef@\halfroottwo{.70710678}
  1789. \xydef@\halfrootthree{.8660254}
  1790. \DOCMODE)
  1791.  
  1792. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1793.  
  1794. \paragraph*{Procedure:}
  1795.  
  1796.     The code chosen by the parsing is very simple; the only tricky bit is
  1797.     to ensure that |\basefromthebase@| always expands to set the current
  1798.     base.
  1799.  
  1800. \DOCMODE(
  1801. \xydef@\vfromcartesian@#1{\vfromcartesian@@#1@}
  1802.  
  1803. \xydef@\vfromcartesian@@#1,#2@{%
  1804.  \Xc=\Xorigin \advance\Xc#1\Xxbase \advance\Xc#2\Xybase
  1805.  \Yc=\Yorigin \advance\Yc#1\Yxbase \advance\Yc#2\Yybase}
  1806.  
  1807. \xydef@\setbase@#1#2#3#4{%
  1808.  \Xorigin=#1\relax \Yorigin=#2\relax
  1809.  \Xxbase=#3\relax \advance\Xxbase-\Xorigin
  1810.  \Yxbase=#4\relax \advance\Yxbase-\Yorigin
  1811.  \Xybase=-\Yxbase \Yybase=\Xxbase}
  1812.  
  1813. \xydef@\setbase@@#1#2{%
  1814.  \Xybase=#1\relax \advance\Xybase-\Xorigin
  1815.  \Yybase=#2\relax \advance\Yybase-\Yorigin}
  1816.  
  1817. \xydef@\basefromthebase@{\Xorigin=\the\Xorigin \Yorigin=\the\Yorigin
  1818.   \Xxbase=\the\Xxbase \Yxbase=\the\Yxbase
  1819.   \Xybase=\the\Xybase \Yybase=\the\Yybase}
  1820. \DOCMODE)
  1821.  
  1822. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1823.  
  1824. \note??=[angle in current base]
  1825. %
  1826.     An "angle" $\alpha$ in \Xy-pic is the same as the coordinate pair
  1827.     $|(|\cos\alpha|,|\sin\alpha|)|$ where $\alpha$ must be an integer
  1828.     interpreted as a number of degrees.  Thus the <vector> |a(0)| is the
  1829.     same as |(1,0)| and |a(90)| as |(0,1)|, etc.
  1830.  
  1831. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1832.  
  1833.     The translation involves several steps: (??_[ang1])~Normalise the
  1834.     argument to be within $[0^\circ:360^\circ[$. (??_[ang2])~Flip angle
  1835.     around $x$-axis and then $y$-axis to ensure it is in the first
  1836.     quadrant, \ie, within $[0^\circ:90^\circ[$.  (??_[ang3])~Flip around
  1837.     diagonal to ensure angle within    $[0^\circ:45^\circ[$.
  1838.     (??_[ang4])~Find values $\phi\le\alpha\lt\psi$ from the table in
  1839.     figure~??[f.angles] (using recursive table lookup -- at most 3 tests
  1840.     needed). (??_[ang5])~build vector $(x,y)$ interpolated between the
  1841.     sin/cos values for $\phi$ and $\psi$ using the formula
  1842. $$
  1843.  \left(\cos\phi + k(\cos\psi-\cos\phi) ,
  1844.  \sin\phi + k(\sin\psi-\sin\phi) \right) ~,
  1845.  \quad\hbox{where}~k = \frac{\alpha-\phi}{\psi-\phi}
  1846. $$
  1847.     (??_[angx])~build the chosen vector.
  1848.  
  1849. \begin{figure}
  1850.     \noindent Vectors for angles in $[0^\circ:45^\circ]$: contains all
  1851.     angles required to typeset fractions up to $\frac{n}{12}\times2\pi$,
  1852.     $\frac1{16}\times2\pi$, and $\frac1{24}\times2\pi$ exactly, and two
  1853.     extra low ones to ensure that all gaps are less than $5^\circ$ and
  1854.     the precision of all sine/cosines better than $\frac1{1000}$.
  1855.  $$
  1856.   \small
  1857.   \def"{\vphantom{\frac()}\frac}
  1858.   \begin{array}{\otherbar l\otherbar r@{~}l\otherbar c\otherbar c\otherbar}
  1859.   \hline
  1860.     ~\alpha    & (\cos\alpha, & \sin\alpha) & \hbox{fractions of $2\pi$} &
  1861.     \hbox{flipped fractions of $2\pi$} \\ 
  1862.   \hline
  1863.     ~0&(1,&0) & "0{n}
  1864.           & "12,"14,"24,"28,"34,"36,"3{12},"48,"5{10},"68,"6{12},"9{12} \\
  1865.     ~4.090909 & (.99677570, & .08023846) & - & - \\
  1866.     ~6        & (.99452190, & .10452846) & - & - \\
  1867.     ~8.181818 & (.98982144, & .14231484) & "3{11} & "8{11} \\
  1868.     10        & (.98480775, & .17364818) & "79 & "29 \\
  1869.     12.857143 & (.97492791, & .22252093) & "27 & "57 \\
  1870.     15        & (.96592583, & .25881905) & "1{24} & \\
  1871.     16.363636 & (.95949297, & .28173256) & "6{11} & "5{11} \\
  1872.     18 & (.95105652, & .30901699) & "3{10},"45,"8{10} & "15,"2{10},"7{10} \\
  1873.     20        & (.93969262, & .34202014) & "59 & "49 \\
  1874.     22.5      & (.92387953, & .38268343) & "1{16} & \\
  1875.     24.545455 & (.90963200, & .41541501) & "9{11} & "2{11} \\
  1876.     25.714286 & (.90096887, & .43388374) & "47 & "37 \\
  1877.     30 & (.86602540, & .5) & "13,"1{12},"26,"39,"4{12},"56,"7{12},"{10}{12}
  1878.                & "16,"23,"2{12},"46,"5{12},"69,"8{12},"{11}{12} \\
  1879.     32.727273 & (.84125353, & .54064082) & "1{11} & "{10}{11} \\
  1880.     36 & (.80901699, & .58778525) & "1{10},"35,"6{10} & "25,"4{10},"9{10} \\
  1881.     38.571429 & (.78183148, & .62348980) & "67 & "17 \\
  1882.     40        & (.76604444, & .64278761) & "19 & "89 \\
  1883.     40.909091 & (.75574957, & .65486073) & "4{11} & "7{11} \\
  1884.     45        & (.70710678, & .70710678) & "18,"38,"58,"78 & - \\
  1885.   \hline
  1886.   \end{array}
  1887.  $$
  1888.  \caption{Computing angle vectors}
  1889.  ??=[f.angles]
  1890. \end{figure}
  1891.  
  1892. \DOCMODE(
  1893. \xydef@\vfromcartesianangle@#1{\enter@\basefromthebase@ \R@=#1\p@
  1894.  \B@=360\p@                                     %?*[ang1]
  1895.  \loop@ \ifdim\R@<\z@ \advance\R@\B@ \repeat@
  1896.  \loop@ \ifdim\R@>\B@ \advance\R@-\B@ \repeat@
  1897.  \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@             %?*[ang2]
  1898.   \Xybase=-\Xybase \Yybase=-\Yybase \fi
  1899.  \B@=180\p@
  1900.  \ifdim\R@<.5\B@\else \R@=-\R@ \advance\R@\B@
  1901.   \Xxbase=-\Xxbase \Yxbase=-\Yxbase \fi
  1902.  \B@=90\p@                            %?*[ang3]
  1903.  \ifdim\R@<.5\B@ \let\nextiii@=\literal@
  1904.  \else \R@=-\R@ \advance\R@\B@ \def\nextiii@##1,##2@{##2,##1@}\fi
  1905.  \dimen@=\z@ \DN@{1,0@}%                    %?*[ang4]
  1906.  \dimen@ii=45\p@ \DNii@{.70710678,.70710678@}%
  1907.  \chooseangleinterval@
  1908.  {\chooseangleinterval@
  1909.   {\chooseangleinterval@
  1910.    {\chooseangleinterval@
  1911.     {\chooseangleinterval@
  1912.      {}%
  1913.      {4.090909}{.99677570,.08023846@}%
  1914.      {}}%
  1915.     {6}{.99677570,.08023846@}%
  1916.     {\chooseangleinterval@
  1917.      {}%
  1918.      {8.181818}{.98982144,.14231484@}%
  1919.      {}}}%
  1920.    {10}{.98480775,.17364818@}%
  1921.    {\chooseangleinterval@
  1922.     {}%
  1923.     {12.857143}{.97492791,.22252093@}%
  1924.     {}}}%
  1925.   {15}{.96592583,.25881905@}%
  1926.   {\chooseangleinterval@
  1927.    {\chooseangleinterval@
  1928.     {}%
  1929.     {16.363636}{.95949297,.28173256@}%
  1930.     {}}%
  1931.    {18}{.95105652,.30901699@}%
  1932.    {\chooseangleinterval@
  1933.     {}%
  1934.     {20}{.93969262,.34202014@}%
  1935.     {}}}}%
  1936.  {22.5}{.92387953,.38268343@}%
  1937.  {\chooseangleinterval@
  1938.   {\chooseangleinterval@
  1939.    {\chooseangleinterval@
  1940.     {}%
  1941.     {24.545455}{.90963200,.41541501@}%
  1942.     {}}%
  1943.    {25.714286}{.90096887,.43388374@}%
  1944.    {}}%
  1945.   {30}{.86602540,.5@}%
  1946.   {\chooseangleinterval@
  1947.    {\chooseangleinterval@
  1948.     {}%
  1949.     {32.727273}{.84125353,.54064082@}%
  1950.     {}}%
  1951.    {36}{.80901699,.58778525@}%
  1952.    {\chooseangleinterval@
  1953.     {\chooseangleinterval@
  1954.      {}%
  1955.      {38.571429}{.78183148,.62348980@}%
  1956.      {}}%
  1957.     {40.909091}{.75574957,.65486073@}%
  1958.     {\chooseangleinterval@
  1959.      {}%
  1960.      {40}{.76604444,.64278761@}%
  1961.      {}}}}}%
  1962.  \A@=\R@ \advance\A@-\dimen@                    %?*[ang5]
  1963.  \ifdim\ifdim\A@<\z@-\fi\A@<.01\p@ \edef\next@{\expandafter\nextiii@\next@}%
  1964.  \else \B@=\dimen@ii \advance\B@-\R@ 
  1965.   \ifdim\A@<\B@ \dimen@=\toradians@\A@
  1966.    \edef\next@{\next@ \expandafter\removePT@\the\dimen@ @}%
  1967.   \else \dimen@=-\toradians@\B@
  1968.    \edef\next@{\nextii@ \expandafter\removePT@\the\dimen@ @}%
  1969.   \fi
  1970.   \expandafter\interpolatepoint@\next@
  1971.   \edef\next@{\expandafter\nextiii@\next@}%
  1972.  \fi 
  1973.  \expandafter\vfromcartesian@@\next@                %?*[angx]
  1974.  \leave@}
  1975.  
  1976. \xydef@\chooseangleinterval@#1#2#3#4{%
  1977.  \B@=#2\p@ \def\next{#3}%
  1978.  \ifdim\R@<\B@ \dimen@ii=\B@ \let\nextii@=\next #1%
  1979.  \else \dimen@=\B@ \let\next@=\next \ifdim\B@<\R@ #4\fi\fi}
  1980.  
  1981. \xydef@\interpolateinterval@#1,#2@#3,#4@{%
  1982.  \A@=#1\p@ \dimen@=#3\p@ \advance\dimen@-\A@ \advance\A@\next\dimen@
  1983.  \B@=#2\p@ \dimen@=#4\p@ \advance\dimen@-\B@ \advance\B@\next\dimen@
  1984.  \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
  1985.  
  1986. \xydef@\toradians@{0.01745329}
  1987.  
  1988. \xydef@\interpolatepoint@#1,#2@#3@{%
  1989.  \A@=#1\p@ \dimen@ii=#3\A@ \dimen@ii=-.5\dimen@ii \advance\A@#3\dimen@ii
  1990.   \dimen@=-#2\p@ \advance\A@#3\dimen@
  1991.  \B@=#2\p@ \dimen@ii=#3\B@ \dimen@ii=-.5\dimen@ii \advance\B@#3\dimen@ii
  1992.   \dimen@=#1\p@ \advance\B@#3\dimen@
  1993.  \edef\next@{\expandafter\removePT@\the\A@,\expandafter\removePT@\the\B@ @}}
  1994. \DOCMODE)
  1995.  
  1996.     Here is a test of all the directions:
  1997. $$
  1998. \def\a(#1){\save"o";a(#1)**\dir{-}*+__!P{\scriptscriptstyle#1}\restore}
  1999. \def\ad(#1){\save"o",a(#1)*{\cdot}\restore}
  2000. %
  2001. \newcount\n \newcount\m
  2002. \xy (50,0):0*[o]\cir<4pt>{}="o"\relax
  2003. \n=0 %
  2004. \loop \expandafter\a\expandafter(\the\n)%
  2005.  \m=\n
  2006.  \advance\m1 \expandafter\ad\expandafter(\the\m)%
  2007.  \advance\m1 \expandafter\ad\expandafter(\the\m)%
  2008.  \advance\m1 \expandafter\ad\expandafter(\the\m)%
  2009.  \advance\m1 \expandafter\ad\expandafter(\the\m)%
  2010.  \advance\n5 \ifnum361>\n\relax \repeat
  2011. \endxy
  2012. $$
  2013.  
  2014. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2015.  
  2016. \note??=[drop]
  2017. %
  2018.     To "drop" an <object> at $c$ with |*| means to actually physically
  2019.     typeset it in the picture with reference position at $c$---how this
  2020.     is done depends on the <object> in question and is described in
  2021.     detail in~\S??[object].  The intuition with a drop is to do something
  2022.     that typesets something a $|<|X_c|,|Y_c|>|$ and sets the edge of $c$
  2023.     accordingly.
  2024.  
  2025. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2026.  
  2027. \subparagraph*{Procedure:}
  2028.  
  2029.     (??_[drop1])~sets up the direction to allow for directionals and
  2030.     builds the requested <object> in the (global) |\lastobjectbox@| box,
  2031.     (??_[drop2])~adjust the picture size unless it is a hidden object,
  2032.     setting $|\dimen@| = X_c-L_c$, and (??_[drop3])~drop the object in the
  2033.     picture at the right point by setting |box0| and using the |\Drop@@|
  2034.     method.
  2035.  
  2036. \DOCMODE(
  2037. \xydef@\drop@#1#2{%                        %?*[drop1]
  2038.  \global\setbox\lastobjectbox@=\object#1{#2}%
  2039.  \ifHidden@ \dimen@=\Xc \advance\dimen@-\Lc \else        %?*[drop2]
  2040.   \dimen@=\Yc \advance\dimen@ \Uc \ifdim\Ymax<\dimen@ \Ymax=\dimen@ \fi
  2041.   \dimen@=\Yc \advance\dimen@-\Dc \ifdim\dimen@<\Ymin \Ymin=\dimen@ \fi
  2042.   \dimen@=\Xc \advance\dimen@ \Rc \ifdim\Xmax<\dimen@ \Xmax=\dimen@ \fi
  2043.   \dimen@=\Xc \advance\dimen@-\Lc \ifdim\dimen@<\Xmin \Xmin=\dimen@ \fi \fi
  2044.  \ifInvisible@\else                        %?*[drop3]
  2045.   \setboxz@h{\kern\dimen@ \raise\Yc\box\lastobjectbox@}%
  2046.   \ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi}
  2047. \DOCMODE)
  2048.  
  2049.     \NOTE: All typesetting into a picture should use or emulate |\drop@|!
  2050.  
  2051. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2052.  
  2053. \note??=[connect]
  2054. %
  2055.     The "connect" operation |**| will first compute a number of internal
  2056.     parameters describing the direction from~$p$ to~$c$ and then typesets
  2057.     a connection filled with copies of the <object> as illustrated
  2058.     in~\S??[basics.connect].  The exact details of the connection depend
  2059.     on the actual <object> and are described in general in~\S??[object].
  2060.     The intuition with a connection is that it is something that typesets
  2061.     something connecting $p$ and $c$ sets the |?| <pos> operator up
  2062.     accordingly.
  2063.  
  2064. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2065.  
  2066. \subparagraph*{Procedure:}
  2067.  
  2068.     Set up the direction to allow for directional objects, then save
  2069.     $c$, build the <object> in |\lastobjectbox@|, restore $c$, and perform
  2070.     the |\Connect@@| method to connect using |\lastobjectbox@|.
  2071.  
  2072. \DOCMODE(
  2073. \xydef@\connect@#1#2{\setupDirection@ \enter@{\cfromthec@}%
  2074.  \global\setbox\lastobjectbox@=\object#1{#2}\leave@
  2075.  \Connect@@}
  2076. \DOCMODE)
  2077.  
  2078. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2079.  
  2080. \note??=[shave]??=[pick place]??=[slide]??=[<place>]
  2081. %
  2082.     Using |?| will ``pick a place'' along the most recent connection
  2083.     typeset with |**|.  What exactly this means is determined by the
  2084.     object that was used for the connection and by the modifiers
  2085.     described in general terms here.
  2086.  
  2087.     The ``shave'' modifiers in a <place>, |<| and |>|, change the default
  2088.     <factor>, $f$, and how it is used, by `moving' the positions that
  2089.     correspond to |(0)| and |(1)| (respectively): These are initially set
  2090.     equal to~$p$ and~$c$, but shaving will move them to the point on the
  2091.     edge of $p$ and $c$ where the connection ``leaves/enters'' them, and
  2092.     change the default $f$ as indicated.  When one end has already been
  2093.     shaved thus then subsequent shaves will correspond to sliding the
  2094.     appropriate position(s) a \TeX\ ??c![\jot] (usually equal to |3pt|)
  2095.     further towards the other end of the connection (and past it).
  2096.     Finally the "pick" action will pick the position located the fraction
  2097.     $f$ of the way from |(0)| to |(1)| where $f=|0.5|$ if it was not set
  2098.     (by |<|, |>|, or explicitly).
  2099.  
  2100.     Finally, the <slide> will move the position a dimension further along
  2101.     the connection at the picked position.  For straight connections (the
  2102.     only ones kernel \XY-pic provides) this is the same as adding a
  2103.     vector in the tangent direction, \ie, $|?|\dots|/|A|/|$ is the same
  2104.     as $|?|\dots|+/|A|/|$.
  2105.  
  2106.     All this is probably best illustrated with some examples: each
  2107.     $\otimes$ in figure~??[f.places] is typeset by a sequence of the form
  2108.     $p$|;| $c$ |**\dir{.}| |?|<place> |*{\oplus}| where we indicate the
  2109.     |?|<place> in each case.
  2110.  
  2111. \begin{figure*}[tp]
  2112. $$
  2113.  %
  2114.  \def\[#1]#2{\def\2{#2}%
  2115.   \POS "p";"c"**{}
  2116.   #2*+=[o]{\oplus}="x"*=<5em,3em>{}-#1*!#1\hbox{{\tt\codeof\2}};
  2117.   "x"**\dir{-}?>*\dir{>}\ignorespaces}%
  2118.  %
  2119. \xy
  2120.  <0pt,110pt>*[o]=<20pt>{}="p"*\frm{oo}+L*!RC\hbox{$p$ is circular:~},
  2121.  <270pt,0pt>*=<4em>\txt<4em>{$c$ is a square text!}="c",{\shaded\framed},
  2122.  "p";"c"**\dir{--}\relax
  2123.  %
  2124.  \[UR]{?(0)}
  2125.  \[UR]{?(1)}
  2126.  \[UR]{?}
  2127.  \[UR]{?(.7)}
  2128.  %
  2129.  \[D]{?<>(.5)}
  2130.  \[DL]{?<>(.2)(.5)}
  2131.  \[DL]{?<}
  2132.  \[UR]{?<<<}
  2133.  \[UR]{?<<</1cm/}
  2134.  \[D]{?<(0)}
  2135.  \[DL]{?>}
  2136.  \[D]{?>>>>}
  2137.  %
  2138.  \[DL]{?<>(.7)}
  2139.  \[D]{?>(.7)}
  2140. \endxy
  2141. $$
  2142. \caption{Example \protect<place>s}??=[f.places]
  2143. \end{figure*}
  2144.  
  2145. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2146.  
  2147. \paragraph*{Procedure:}
  2148.  
  2149.     The code for parsing <place> is the following.  To get first |<>| to
  2150.     move to edge and the remaining to move a |\jot| we have both initial
  2151.     and continuing versions for each, the idea being that the second and
  2152.     following go to the edge of a small temporary object with radius
  2153.     |\jot|.
  2154.  
  2155.     \NOTE: This parser tests the "new parsing principle" that |\xy@|
  2156.     should always be called as |\xy@{| "source" |}{| "target" |}|!
  2157.  
  2158. \DOCMODE(
  2159. \xydef@\afterPLACE#1{%
  2160.  \DN@##1{\def\afterPLACE@{\xy@@\leave@ \def\afterPLACE@{##1}#1}}%
  2161.  \expandafter\next@\expandafter{\afterPLACE@}%
  2162.  \xy@@{\enter@{\pfromthep@}%
  2163.   \Creset@@
  2164.   \def\PLACEf@{{.5}}%
  2165.   \let\PLACEedgep@@=\PLACEedgep@ \let\PLACEedgec@@=\PLACEedgec@}%
  2166.  \xyFN@\PLACE@}
  2167.  
  2168. \xydef@\PLACEf@{}
  2169.  
  2170. \xydef@\PLACEedgep@@{}
  2171. \xydef@\PLACEedgec@@{}
  2172.  
  2173. \xydef@\PLACEedgep@{\Cshavep@@ \def\PLACEedgep@@{\Cslidep@@\jot}}
  2174. \xydef@\PLACEedgec@{\Cshavec@@ \def\PLACEedgec@@{\Cslidec@@{-\jot}}}
  2175.  
  2176. \xylet@\afterPLACE@=\empty
  2177.  
  2178. \xydef@\PLACE@{%
  2179.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@}%gobble spaces
  2180.  \else\addLT@\ifx \next
  2181.   \addLT@\DN@{\addLT@\xy@{\def\PLACEf@{{0}}\PLACEedgep@@}\xyFN@\PLACE@}%
  2182.  \else\addGT@\ifx \next
  2183.   \addGT@\DN@{\addGT@\xy@{\def\PLACEf@{{1}}\PLACEedgec@@}\xyFN@\PLACE@}%
  2184.  \else\ifx (\next %)
  2185.   \DN@(##1){\def\PLACEf@{{##1}}\xy@{(##1)}{\def\PLACEf@{{##1}}}\xyFN@\PLACE@}%
  2186.  \else
  2187.   \DN@{\xy@@{\expandafter\Calong@@\PLACEf@ \czeroEdge@}\PLACE@@}%
  2188.  \fi\fi\fi\fi \next@}
  2189.  
  2190. \xydef@\PLACE@@{%
  2191.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\PLACE@@}%gobble spaces
  2192.  \else\ifx /\next \DN@/##1/{\xy@{/##1/}{\Cslidec@@{##1}}\afterPLACE@}%
  2193.  \else \let\next@=\afterPLACE@
  2194.  \fi\fi \next@}
  2195. \DOCMODE)
  2196.  
  2197. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2198.  
  2199. \note??=[axis intersection]
  2200. %
  2201.     The positions denoted by the "axis intersection"
  2202.     <coord>inates~??c![x] and~??c![y] are the points where the line
  2203.     through $p$ and $c$ intersects with each axis.  These are probably
  2204.     best illustrated by the following example where they are shown for a
  2205.     coordinate system and a $p,c$ pair:
  2206. $$
  2207.  \xy;<1cm,.5cm>:<-.5cm,.5cm>::
  2208.   (0,0)*+!UR{"origin"};
  2209.   (1,0)*+!DR{"xbase"}**\dir{-}?>*\dir{>},
  2210.   (0,0);(0,1)*+!DR{"ybase"}**\dir{-}?>*\dir{>},
  2211.   (0.5,-1)="p"*\dir{o}*!LU\hbox{~$p$};
  2212.   p+<.25cm,.5cm>="c"*\dir{o}*!LU\hbox{~$c$}*{}?(1),
  2213.   %
  2214.   "p";"c",x*+!LD{|x|}*\dir{*}*{}**\dir{.};(1,0)**\dir{.},
  2215.   "p";"c",y*!U{\strut|y|}*\dir{*}*{}**\dir{.};(0,0)**\dir{.},
  2216.  \endxy
  2217. $$
  2218.  
  2219. \begin{exercise}
  2220. %
  2221.     Given predefined points $A$, $B$, $C$, and $D$ (stored as objects
  2222.     |"A"|, |"B"|, |"C"|, and |"D"|), write a <coord> specification that
  2223.     will return the point where the lines $\overline{AB}$ and
  2224.     $\overline{CD}$ cross as the point marked with a large circle here:
  2225. %
  2226. \begin{code}
  2227. \xy
  2228.  %
  2229.  % set up and mark A, B, C, and D:
  2230.  (0,0)="A"  *\cir<1pt>{}*+!DR{A},
  2231.  (7,10)="B" *\cir<1pt>{}*+!DR{B},
  2232.  (13,8)="C" *\cir<1pt>{}*+!DL{C},
  2233.  (15,4)="D" *\cir<1pt>{}*+!DL{D},
  2234.  %
  2235.  % goto intersection and name+circle it:
  2236.  {"A";"B":"C";"D",x} ="I" *\cir<3pt>{},
  2237.  %
  2238.  % make dotted lines:
  2239.  "I";"A"**{} +/1pc/;-/1pc/ **\dir{..},
  2240.  "I";"D"**{} +/1pc/;-/1pc/ **\dir{..}
  2241.  %
  2242. \endxy
  2243. \end{code}
  2244. $$\docode$$
  2245. %
  2246. \answertext{The <coord> ``|{"A";"B":| |"C";"D",| |x}|'' returns the cross
  2247.     point. Here is how the author typeset the diagram in the exercise:}
  2248. \answercode
  2249. \answertext\displaycode
  2250. \end{exercise}
  2251.  
  2252. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2253.  
  2254. \paragraph*{Procedure:}
  2255.  
  2256.     We solve the following equation in $a,b$:
  2257. $$
  2258.  "origin" + a*|<|R_c|,|U_c|>| = c - b*(c-p)
  2259. $$
  2260.     and then set
  2261. $$
  2262.  |<|X_c|,|Y_c|>| := |<|X_c|,|Y_c|>| - b*(c-p)
  2263.  \quad\text{with zero size}\quad
  2264.  D_c,U_c,L_c,R_c := 0,0,0,0. 
  2265. $$
  2266.     The code uses $c=(X_c,Y_c,D_c,U_c,L_c,R_c)$ and $A,B$ as temporaries
  2267.     and computes:
  2268. $$
  2269. \begin{array}{rcl}
  2270.  |<|dX|,|dY|>| &:=& |<|X_c|,|Y_c|>| - |<|X_p,Y_p|>| \\[1pt]
  2271.  |<|A|,|B|>| &:=& |<|X_c|,|Y_c|>| - |<|X_"origin"|,|Y_"origin"|>| \\[1pt]
  2272.  |<|D_c|,|L_c|>| &:=& |<| \Det{R& dX\\U&dY} |,|
  2273.               \Det{R&A\\U&B} |>| \\[1pt]
  2274.  |<|X_c|,|Y_c|>| &:=& |<|X_c|,|Y_c|>| - (L_c/D_c)*|<|dX|,|dY|>|
  2275. \end{array}
  2276. $$
  2277.     where we really do $D := (R/|pt|)dY - (U/|pt|)dX$ and similarly for
  2278.     $L$. 
  2279.  
  2280. \DOCMODE(
  2281. \xydef@\intersect@{%
  2282.  \dX=\Xc \advance\dX-\Xp \dY=\Yc \advance\dY-\Yp
  2283.  \A@=\Xc \advance\A@-\Xorigin \B@=\Yc \advance\B@-\Yorigin
  2284.  \edef\next@{\expandafter\removePT@\the\Rc}%
  2285.  \edef\nextii@{\expandafter\removePT@\the\Uc}%
  2286.  \Dc=\next@\dY \advance\Dc-\nextii@\dX \divide\Dc\KK@
  2287.  \Lc=\next@\B@ \advance\Lc-\nextii@\A@ \divide\Lc\KK@
  2288.  \ifdim\Dc=\z@\DN@{0}\else \quotient@\next@\Lc\Dc \fi
  2289.  \advance\Xc-\next@\dX \advance\Yc-\next@\dY
  2290.  \czeroEdge@}
  2291. \DOCMODE)
  2292.  
  2293. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2294.  
  2295. \note??=[group]
  2296. %
  2297.     A <pos> <decor> "grouped" in |{}|-braces is interpreted in a local
  2298.     scope in the sense that any $p$ and "base" built within it are
  2299.     forgotten afterwards.  \REMARK: Only $p$ and "base" are restored---it
  2300.     is not a \TeX\ group.
  2301.  
  2302. \begin{exercise}
  2303.     What is the effect of the <coord>inate ``|{;}|''?
  2304. \answertext{To copy the $p$ value to $c$, \ie, equivalent to ``??c![p]''.}
  2305. \end{exercise}
  2306.  
  2307.  
  2308. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2309.  
  2310.     The code is inside |\POS@|.
  2311.  
  2312. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2313.  
  2314. \note??=[in <direction>]
  2315. %
  2316.     The vector $|/|Z|/|$, where $Z$ is a <dimen>sion, is the same as the
  2317.     vector $|<|Z\cos\alpha|,|Z\sin\alpha|>|$ where $\alpha$ is the angle
  2318.     of the last direction set by a connection (|**|) or subsequent
  2319.     placement (|?|) position.
  2320.  
  2321. \DOCMODE(
  2322. \xydef@\vfromslide@#1{\enter@\DirectionfromtheDirection@ \begingroup
  2323.  \plainxy@\afterDIRECTIONorEMPTY\vfromslide@i\vfromslide@i#1@}
  2324.  
  2325. \xydef@\vfromslide@i#1@{%
  2326.  \edef\next{\endgroup 
  2327.   \dimen@=#1\relax \Xc=\cosDirection\dimen@ \Yc=\sinDirection\dimen@}\next
  2328.  \leave@}
  2329. \DOCMODE)
  2330.  
  2331.     It is possible to give a <direction> as described in the next
  2332.     section (figure~??[f.object] and note~??[<direction>] in
  2333.     particular) that will then be used to set the value of
  2334.     $\alpha$.
  2335.  
  2336. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2337.  
  2338. \note??=[offset]??=[corner]
  2339. %
  2340.     A <corner> is an offset from the current $|<|X_c|,|Y_c|>|$ position
  2341.     to a specific position on the edge of the $c$ object (the two-letter
  2342.     ones may be given in any combination):
  2343. $$
  2344. \def\[#1]{\POS"box"+#1="x";"box"
  2345.  **{} ?</-2em/*+\hbox{\tt#1};"x",**\dir{-}?>*\dir{>}}
  2346. %
  2347. \xy.(-5,-4).(15,9)*\frm{-}="box"*{c}="c";
  2348.  "box"+L**\dir{.}, "box"+R**\dir{.}, "box"+D**\dir{.}, "box"+U**\dir{.}
  2349. %
  2350.  \[L] \[R] \[D] \[U]
  2351.  \[LD]\[RD]\[LU]\[RU]
  2352.  \[CL]\[CR]\[DC]\[UC] \[C] \[P]
  2353.  \POS"box"+(-20,-7)*{p}="p";"c"**\dir{--},"box"**{}\[E]
  2354. \endxy
  2355. $$
  2356.     The `proportional' point |P| is computed in a complex way to make the
  2357.     object look as much `away from $p$' as possible.
  2358.  
  2359.     Finally, a following $|(|f|)|$ suffix will multiply the offset vector
  2360.     by the <factor> $f$.
  2361.  
  2362. \begin{exercise}
  2363.     What is the difference between the <pos>itions |c?<| and |c+E|?
  2364. \answertext{When using the kernel connections that are all straight there is
  2365.     no difference, \eg, |**{}?<| and |**{}+E| denote exactly the same
  2366.     position.  However, for other connections it is not necessarily the
  2367.     case that the point where the connection enters the current object,
  2368.     denoted by |?<|, and the point where the straight line from $p$
  2369.     enters the object, denoted by |+E|, coincide.}
  2370. \end{exercise}
  2371.  
  2372. \begin{exercise}
  2373. \begin{code}
  2374. \xy *=<3cm,1cm>\txt{Box}*\frm{-}
  2375.  !U!R(.5) *\frm{..}*{\bullet} \endxy
  2376. \end{code}
  2377. %
  2378.     What does
  2379. %
  2380. \displaycode
  2381. \noindent
  2382.     typeset?  "Hint": |\frm| is defined by the frame extension and just
  2383.     typesets a frame of the kind indicated by the argument.
  2384. %
  2385. \answercode
  2386. \answertext{The code typesets the picture $$\docode$$}
  2387. \end{exercise}
  2388.  
  2389.     \BUG: Currently only the single-letter corners (??c![L], ??c![R],
  2390.     ??c![D], ??c![U], ??c![C], ??c![E], and ??c![P]) will work for any
  2391.     shape---the others silently assume that the shape is rectangular.
  2392.  
  2393. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2394.  
  2395. \note??=[stack]
  2396. %
  2397.     The "stack" is a special construction useful for storing a sequence
  2398.     of <pos>itions.  |@i|~initialises, \ie, clears the stack such that it
  2399.     contains no positions, |@+| `??w![push]es' $c$ onto it, \ie, adds on
  2400.     the `top' of the stack, increasing the `depth' by one, and
  2401.     |@-|~`??w![pop]s' the top element off the stack, decreasing the depth
  2402.     by one.  It is an error to pop when the stack is empty.
  2403.  
  2404.     The special <coord>inates~|s|$n$, where $n$~is either a single digit
  2405.     or a positive integer in |{}|s, refer to the $n$'th position "below
  2406.     the top", \ie, |s0| is the position on the top, |s1| the one below
  2407.     that, etc.
  2408.  
  2409. \begin{exercise}
  2410.     Assume the positions $A$, $B$, $C$, and $D$ are defined.
  2411.     What does the stack contain after the <pos>ition |@i,| $A$|@+,|
  2412.     $B$|@+,| |@-,| $C$|,| $D$|@+|~?
  2413. \answertext{|s0| contains $D$ and |s1| contains~$A$.}
  2414. \end{exercise}
  2415.  
  2416.     Furthermore, |@(| `hides' the current stack and creates a fresh stack
  2417.     that can be used as above and once it has served its purpose |@)|
  2418.     will purge it and reestablish the saved stack (issuing a warning
  2419.     message if the purged stack is non-empty).
  2420.  
  2421. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2422.  
  2423.     First the stack top and bottom, both initially~$-1$:
  2424.  
  2425. \DOCMODE(
  2426. \xydef@\sbot@{-1}
  2427. \xydef@\stop@{-1}
  2428. \DOCMODE)
  2429.  
  2430.     Next the function to set $c\from|s|n$: only valid when $"bot" \lt
  2431.     n+"bot" \lt "top"$.
  2432.  
  2433. \DOCMODE(
  2434. \xydef@\cfroms@#1{%
  2435.  \count@=\stop@ \advance\count@-#1\relax
  2436.  \DN@{\count@=\stop@ \advance\count@-\sbot@
  2437.   \xyerror@{stack index out of range (should be 0..\the\count@)}{}}%
  2438.  \ifnum\count@>\sbot@ \ifnum\count@>\stop@\else \let\next@=\relax \fi\fi
  2439.  \csname S@\the\count@\endcsname}
  2440. \DOCMODE)
  2441.  
  2442.     Finally the actual code to do the stack operations: it depends on the
  2443.     `code' passed after |@|; spaces are not allowed:
  2444.  
  2445. \DOCMODE(
  2446. \xydef@\STACK@{%
  2447.  \addPLUS@\ifx\next
  2448.   \addPLUS@\DN@{\xy@{@+}{}\afterCOORD{\xy@@\spushc@ \xyFN@\POS@}}%
  2449.  \else\addDASH@\ifx\next
  2450.   \addDASH@\DN@{\xy@{@-}{}\afterCOORD{\xy@@\spop@ \xyFN@\POS@}}%
  2451.  \else \ifx i\next \DN@ i{\xy@{@i}\sinit@ \xyFN@\POS@}%
  2452.  \else \ifx (\next \DN@ ({\xy@{@(}\senter@ \xyFN@\POS@}%
  2453.  \else \ifx )\next \DN@ ){\xy@{@)}\sleave@ \xyFN@\POS@}%
  2454.  \else\addAT@\ifx\next \addAT@\DN@{\xy@{@@}{}\smap@}%
  2455.  \else \DN@##1{\xyerror@{illegal stack command ##1}{}\afterCOORD{\xyFN@\POS@}}%
  2456.  \fi\fi\fi\fi\fi\fi \next@}
  2457.  
  2458. \xydef@\spushc@{%
  2459.  \count@=\stop@ \advance\count@\@ne \edef\stop@{\the\count@}%
  2460.  \expandafter\edef\csname S@\stop@\endcsname{\cfromthec@}}
  2461.  
  2462. \xydef@\spop@{\count@=\stop@
  2463.  \ifnum\count@>\sbot@ \advance\count@\m@ne \edef\stop@{\the\count@}%
  2464.  \else \xyerror@{nothing to pop from stack}{}\fi}
  2465.  
  2466. \xydef@\sinit@{\edef\stop@{\sbot@}}
  2467.  
  2468. \xydef@\senter@{%
  2469.  \count@=\stop@ \advance\count@\@ne
  2470.  \expandafter\edef\csname S@\the\count@\endcsname{\sbot@}%
  2471.  \edef\sbot@{\the\count@}\edef\stop@{\the\count@}}
  2472.  
  2473. \xydef@\sleave@{%
  2474.  \ifnum\sbot@=\stop@\else
  2475.   \xywarning@{leaving non-empty stack}\edef\stop@{\sbot@}\fi
  2476.  \ifnum\sbot@>\m@ne \edef\sbot@{\csname S@\stop@\endcsname}%
  2477.   \count@=\stop@ \advance\count@\m@ne \edef\stop@{\the\count@}%
  2478.  \edef\sbot{\the\count@}\fi}
  2479.  
  2480. \xydef@\sempty@{\ifnum\stop@=\sbot@ TT\else TF\fi}
  2481. \DOCMODE)
  2482.  
  2483. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2484.  
  2485. \note??=[for every stack element]
  2486. %
  2487.     To `do <coord> for every stack element' means to set $c$ to all the
  2488.     elements of the stack, from the bottom and up, and for each interpret
  2489.     the <coord>.  Thus the first interpretation has $c$ set to the bottom
  2490.     element of the stack and the last has $c$ set to~|s0|.  If the stack
  2491.     is empty, the <coord> is not interpreted at all.
  2492.  
  2493.     This can be used to repeat a particular <coord> for several points:
  2494. %
  2495. \begin{code}
  2496. \xy
  2497.  @i @+(0,-10) @+(10,3) @+(20,-5)
  2498.  @@{*{P}}
  2499. \endxy
  2500. \end{code}
  2501. \displaycode
  2502. %
  2503. \noindent will typeset
  2504. %
  2505. $$\docode$$
  2506.  
  2507. \begin{exercise}
  2508.     How would you change the above to connect the points as shown below?
  2509. %
  2510. \begin{code}
  2511. \xy
  2512.  @i @+(0,-10) @+(10,3) @+(20,-5),
  2513.  s0="prev" @@{;"prev";**\dir{-}="prev"}
  2514. \endxy
  2515. \end{code}
  2516. %
  2517. $$\docode$$
  2518. %
  2519. \answercode
  2520. \answertext{This does the job, saving each point to make the previous point
  2521.     available for the next piece:\displaycode\noindent Notice how we
  2522.     first save |s0| because that will be the last point that we run
  2523.     through thus the line is closed.}
  2524. %
  2525. \end{exercise}
  2526.  
  2527. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2528.  
  2529.     |\smap@| maps a <coord> over a stack:
  2530.  
  2531. \DOCMODE(
  2532. \xydef@\xytotoks@#1#2{\addtotoks@{#2}}
  2533. \xydef@\xytotoks@@toksix@#1{\addtotoks@{\toks9={#1}}}
  2534.  
  2535. \xydef@\smap@{%
  2536.  \begingroup \toks@={}\let\xy@=\xytotoks@ \let\oxy@=\xy@
  2537.   \let\xy@@ix@=\xytotoks@@toksix@
  2538.   \afterCOORD{\expandafter\endgroup
  2539.    \expandafter\smapxy@@\expandafter{\the\toks@}\xyFN@\POS@}}
  2540.  
  2541. \xydef@\smapxy@@#1{\xy@@{\edef\smapp@@{\sbot@}\smapxy@i{#1}}}
  2542.  
  2543. \xylet@\smapp@@=\empty
  2544.  
  2545. \xydef@\smapxy@i#1{%
  2546.  \ifnum\smapp@@<\stop@
  2547.   \count@=\smapp@@ \advance\count@\@ne \edef\smapp@@{\the\count@}%
  2548.   \DN@{\csname S@\smapp@@\endcsname #1\relax \smapxy@i{#1}}%
  2549.  \else \let\next@=\relax
  2550.  \fi \next@}
  2551. \DOCMODE)
  2552.  
  2553. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2554.  
  2555. \note??=[save]??=[saved]
  2556. %
  2557.     It is possible to define new <coord>inates on the form |"|<id>|"| by
  2558.     "saving" the current $c$ using the \dots|="|<id>|"| <pos>ition form.
  2559.     Subsequent uses of |"|<id>|"| will then reestablish the $c$ at the
  2560.     time of the saving.
  2561.  
  2562.     Using a |"|<id>|"| that was never defined is an error, however,
  2563.     saving into a name that was previously defined just replaces the
  2564.     definition, \ie, |"|<id>|"| always refers to the last thing saved
  2565.     with that <id>.
  2566.  
  2567.     \NOTE: There is no distinction between <id>s used for saved
  2568.     coordinates and for macros and described in the next note.
  2569.  
  2570. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2571.  
  2572. \note??=[define macro]
  2573. %
  2574.     The general form, |=|<code>|"|<id>|"| can be used to save various
  2575.     things:
  2576. %
  2577. \begin{defs}
  2578.  <code> & effect \cr
  2579. \noalign{\nobreak\smallskip\nobreak\hrule\nobreak\smallskip\nobreak}%
  2580.  |:| & |"|<id>|"| restores current "base" \cr
  2581.  <coord> & |"|<id>|"| interprets <coord> \cr
  2582. \end{defs}
  2583. \noindent\unskip
  2584. %
  2585.     The first form defines |"|<id>|"| to be a macro that restores the
  2586.     current "base".
  2587.  
  2588.     The second does not depend on the state at the time of definition at
  2589.     all; it is a macro definition.  You can pass parameters to such a
  2590.     macro by letting it use coordinates named |"1"|, |"2"|, etc., and
  2591.     then use |="1"|, |="2"|, etc., just before every use of it to set the
  2592.     actual values of these.  \NOTE: it is not possible to use a <coord>
  2593.     of the form |"|<id>|"| directly: write it as |{"|<id>|"}|.
  2594. %
  2595. \begin{exercise}
  2596.     Write a macro |"dbl"| to double the size of the current~$c$ object,
  2597.     \eg, changing it from the dotted to the dashed outline in this
  2598.     figure:
  2599. %
  2600. \begin{code}
  2601. \xy ={.{+DL(2)}.{+UR(2)}}"dbl",
  2602.  *+<3pc,2pc>{+}*\frm{.}, "dbl"*\frm{--}
  2603. \endxy
  2604. \end{code}
  2605. $$
  2606. \docode
  2607. $$
  2608. \answercode
  2609. \answertext{The author used \displaycode\noindent to typeset the figure in
  2610.     the exercise.}
  2611. \end{exercise}
  2612.  
  2613. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2614.  
  2615.     This parser distinguishes between the cases:
  2616.  
  2617. \DOCMODE(
  2618. \xydef@\saveid@{%
  2619.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\saveid@}%gobble spaces
  2620.  \else \ifx "\next\DN@"##1"{\xy@{="##1"}{\idfromc@{##1}}\xyFN@\POS@}%
  2621.  \else \ifx :\next\DN@:##1"##2"{\xy@{=:"##2"}{\idfrombase@{##2}}\xyFN@\POS@}%
  2622.  \else \let\next@=\saveid@COORD
  2623.  \fi\fi\fi \next@}
  2624. \DOCMODE)
  2625.  
  2626.     Here is the code for saving/restoring a position and a base.
  2627.  
  2628.     \TODO: Introduce |\xyprefix@@| to provide a local scope in addition
  2629.     to the global one (where it is empty).
  2630.  
  2631. \DOCMODE(
  2632. \xydef@\xyscope@{}
  2633. \xydef@\xyprefix@@{}
  2634.  
  2635. \xydef@\idfromc@#1{\DN@{#1}%
  2636.  \expandafter\edef\csname Q@\codeof\next@\endcsname{\cfromthec@}}
  2637.  
  2638. \xydef@\idfrombase@#1{\DN@{#1}%
  2639.  \expandafter\edef\csname Q@\codeof\next@\endcsname{\basefromthebase@}}
  2640.  
  2641. \xydef@\saveid@COORD{%
  2642.  \begingroup \toks@={}\let\xy@=\xytotoks@ \let\oxy@=\xy@
  2643.   \let\xy@@ix@=\xytotoks@@toksix@
  2644.   \afterCOORD{\expandafter\saveid@COORDi\expandafter{\the\toks@}}}
  2645.  
  2646. \xydef@\saveid@COORDi#1#2"#3"{\endgroup \xy@@{\idfromxy@{#3}{#1}}\xyFN@\POS@}
  2647.  
  2648. \xydef@\idfromxy@#1#2{\DN@{#1}%
  2649.  \expandafter\def\csname Q@\codeof\next@\endcsname{#2}}
  2650.  
  2651. \xydef@\cfromid@#1{\DNii@{#1}\edef\nextii@{\codeof\nextii@}%
  2652.  \expandafter\let\expandafter\next@\csname Q@\nextii@\endcsname
  2653.  \ifx\next@\relax
  2654.   \xyerror@{<pos> \string"\nextii@\string" not defined}{}%
  2655.  \else \expandafter\next@\fi}
  2656. \DOCMODE)
  2657.  
  2658. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2659.  
  2660. \end{notes}
  2661.  
  2662. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2663.  
  2664.  
  2665.  
  2666. \section{Objects}
  2667. ??=[object]
  2668.  
  2669. \DOCMODE(
  2670. \message{objects,}
  2671. \DOCMODE)
  2672.  
  2673.     Objects are the entities that are manipulated with the |*| and |**|
  2674.     <pos> operations above to actually get some output in \XY-pictures.
  2675.     As for <pos>itions the operations are interpreted strictly from left
  2676.     to right, however, the actual object is built "before" all the
  2677.     <modifier>s take effect.  The syntax of objects is given in
  2678.     figure~??[f.object] with references to the notes below.
  2679.  
  2680. \begin{figure*}[tp]
  2681. \begin{syntax}
  2682. %
  2683.  ??w![<object>]
  2684.   &\iss    & <modifier> <object>
  2685.     & apply <modifier> to <object>
  2686. \cr
  2687.   &\orr    & <objectbox>
  2688.     & build <objectbox> then apply its <modifier>s
  2689. \cr
  2690. \noalign{\smallbreak}
  2691. %
  2692. \cr
  2693.  ??w![<objectbox>]
  2694.   &\iss    & |{| <text> |}|
  2695.     & ??!^[build default] object
  2696. \cr
  2697.   &\orr    & <library object>
  2698.     & use <library object> (see~\S??[objectlib])
  2699. \cr
  2700.   &\orr    & <\TeX\ box> |{| <text> |}|
  2701.     & ??!^[build box] object with <text> using the given <\TeX\ box>
  2702.       command, \eg, ??c![\hbox]
  2703. \cr
  2704.   &\orr    & ??c![\object] <object>
  2705.     & wrap up the <object> as a ??!^[finished object box]
  2706. \cr
  2707.   &\orr    & ??c![\composite] |{| <composite> |}|
  2708.     & build ??!^[composite object box]
  2709. \cr
  2710.   &\orr    & ??c![\xybox] |{| <pos> <decor> |}|
  2711.     & package ??!^[entire \XY-picture as object] with the right size
  2712. \cr
  2713. \noalign{\smallbreak}
  2714. %
  2715.  ??w![<modifier>]
  2716.   &\iss    & |!| <vector>
  2717.     & <object> has its is reference point ??!^[shifted] by <vector>
  2718. \cr
  2719.   &\orr    & |!|
  2720.     & <object> has the original reference point reinstated
  2721. \cr
  2722.   &\orr    & <add op> <size>
  2723.     & change ??!^[<object> size]
  2724. \cr
  2725.   &\orr    & ??c![i] \orr\ ??c![h]
  2726.     & <object> is ??!^[invisible], ??!^[hidden]
  2727. \cr
  2728.   &\orr    & |[| <shape> |]|
  2729.     & <object> is given the specified ??!^[<shape>]
  2730. \cr
  2731.   &\orr    & <direction>
  2732.     & set current direction for this <object>
  2733. \cr
  2734. \noalign{\smallbreak}
  2735. %
  2736.  ??w![<add op>]
  2737.   &\iss    & |+| \orr\ |-| \orr\ |=| \orr\ |+=| \orr\ |-=|
  2738.     & grow, shrink, set, grow to, shrink to
  2739. \cr
  2740. \noalign{\smallbreak}
  2741. %
  2742.  ??w![<size>]
  2743.   &\iss    & <empty>
  2744.     & ??!^[default size]
  2745. \cr
  2746.   &\orr    & <vector>
  2747.     & size as sides of rectangle surrounding the <vector>
  2748. \cr
  2749. \noalign{\smallbreak}
  2750. %
  2751.  ??w![<direction>]
  2752.   &\iss    & <diag>
  2753.     & <diag>onal ??!^[direction]
  2754. \cr
  2755.   &\orr    & ??c![v] <vector>
  2756.     & ??!^[direction] of <vector>
  2757. \cr
  2758.   &\orr    & <direction> ??c![:] <vector>
  2759.     & vector relative to ??!^[<direction>]
  2760. \cr
  2761.   &\orr    & <direction> |_| \orr\ <direction> |^|
  2762.     & $90^\circ$ clockwise/anticlockwise of ??!^[<direction>]
  2763. \cr
  2764. %
  2765.  ??w![<diag>]
  2766.   &\iss    & <empty>
  2767.     & default ??!^[diagonal]
  2768. \cr
  2769.   &\orr    & |l|\orr|r|\orr|d|\orr|u|
  2770.     & left, right, down, up ??!^[diagonal]
  2771. \cr
  2772.   &\orr    & |ld|\orr|rd|\orr|lu|\orr|ru|
  2773.     & left/down, \dots\ ??!^[diagonal]
  2774. \cr
  2775. \noalign{\smallbreak}
  2776. %
  2777.  ??w![<composite>]
  2778.   &\iss    & <object>
  2779.     & first object is required
  2780. \cr
  2781.   &\orr    & <composite> |*| <object>
  2782.     & add <object> to ??!^[composite object box]
  2783. %
  2784. \end{syntax}
  2785. \caption{\protect<object>s.}
  2786. ??=[f.object]
  2787. \end{figure*}
  2788.  
  2789.     \TODO: Explain how strange \TeX\ error messages (first of all |box
  2790.     expected|) can result from incomplete <object> specifications.
  2791.  
  2792. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2793.  
  2794.     We first discuss the parser and then summarise the required methods.
  2795.     The entry point to use of objects is |\object| described in note
  2796.     ??[finished object box].  This should always be used because it
  2797.     initialises the token list and redefines |\xy@| to be |\addtotoks@|
  2798.     such that we can use <pos> parser routines within the <object>!
  2799.  
  2800. \paragraph*{Parsing:}
  2801.  
  2802.     The <object> parser |\OBJECT@| will first parse the <modifier>s,
  2803.     storing the action of each in sequence on the |\toks@| token list.
  2804.     When there are no more modifiers we insert |\objectbox| if we have
  2805.     reached the |{| otherwise we just assume that the rest of the
  2806.     <object> is some kind of box construction.
  2807.  
  2808.     "Note": The <modifier> actions doing shifts are implemented by having
  2809.     an independent vector for the shift: $|<|R_p|,|U_p|>|$ always
  2810.     contains the vector from the current to the original \TeX\ reference
  2811.     point; furthermore the initial $L_c$ is saved as $L_p$ such that we
  2812.     can retrieve the original (\XY-pic) reference point again.  Modifying
  2813.     the $p$ values is safe because all actual changes are done in a local
  2814.     scope after the entire <object> is parsed and we have built the
  2815.     object box (in |\OBJECT@@|).
  2816.  
  2817.     The <modifier>s changing the direction are executed while parsing to
  2818.     make sure that the direction used when building the <object> is
  2819.     right, and restored in the right sequence while evaluating the
  2820.     <modifier>s afterwards.  This is what |\addDirectiontotoks@| is used
  2821.     for.
  2822.  
  2823. \DOCMODE(
  2824. \xydef@\OBJECT@{%
  2825.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\OBJECT@}%gobble spaces
  2826.  \else\ifcat A\noexpand\next \let\next@=\OBJECT@letter
  2827.  \else \let\next@=\OBJECT@other \fi\fi \next@}
  2828.  
  2829. \xydef@\OBJECT@letter{%
  2830.  \ifx i\next
  2831.   \DN@ i{\addtotoks@\Invisible@true \xyFN@\OBJECT@}%
  2832.  \else\ifx h\next
  2833.   \DN@ h{\addtotoks@\Hidden@true \xyFN@\OBJECT@}%
  2834.  \else\ifx o\next \DN@ o{\xywarning@{o modifier used}\OBJECT@shape{o}}%
  2835.  \else\ifx x\next \DN@ x{\xywarning@{x modifier used}\OBJECT@shape{}}%
  2836.  \else \let\next@=\OBJECT@direction
  2837.  \fi\fi\fi\fi \next@}
  2838.  
  2839. \xydef@\OBJECT@other{%
  2840.  \ifx !\next \DN@!{\OBJECT@shift}%
  2841.  \else\addPLUS@\ifx \next \DN@{\OBJECT@change+>}%
  2842.  \else\addDASH@\ifx \next \DN@{\OBJECT@change-<}%
  2843.  \else\addEQ@\ifx \next \DN@{\OBJECT@set}%
  2844.  \else\ifx [\next %]
  2845.   \DN@[##1]{\xy@{[##1]}{\OBJECT@shape{##1}}}%
  2846.  \else\ifx ^\next \let\next@=\OBJECT@direction
  2847.  \else\ifx _\next \let\next@=\OBJECT@direction
  2848.  \else\ifx :\next \let\next@=\OBJECT@direction
  2849.  \else\ifx ?\next
  2850.   \DN@ ?{\xywarning@{\string? modifier used}\xyFN@\OBJECT@direction}%
  2851.  \else \DN@##1##{\OBJECT@@{##1}}%
  2852.  \fi\fi\fi\fi\fi\fi\fi\fi\fi \next@}
  2853.  
  2854. \xydef@\addDirectiontotoks@{\edef\nextiii@{{\DirectionfromtheDirection@}}%
  2855.  \expandafter\addtotoks@\nextiii@}
  2856. \DOCMODE)
  2857.  
  2858.     |\OBJECT@@| is where we actually build the box by ??_[OBJ1]~setting
  2859.     the defaults (including temporarily resetting |\xy@| to execute in
  2860.     case any |\xy@|s are used internally), ??_[OBJ2]~building the object
  2861.     box (which might change them) using |\objectbox| if no other command
  2862.     specified and setting the $D,U,L,R$ dimensions ad required using the
  2863.     |\Leftness@| and |\Upness@| methods, and finally ??_[OBJ3]~setting up
  2864.     the $R_p,U_p$ dimensions (as discussed above) and applying the
  2865.     <modifier>s stored in |\toks@| and dumping the modified box.
  2866.  
  2867. \DOCMODE(
  2868. \xydef@\OBJECT@@#1#2{\Edgec={\objectEdge}%            %?*[OBJ1]
  2869.  \Invisible@false\Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
  2870.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@\relax}%
  2871.  \DN@{#1}\ifx\next@\empty \DNii@{#2}%                %?*[OBJ2]
  2872.   \ifx\nextii@\empty \DN@{\hbox\bgroup\no@}\else \let\next@=\objectbox \fi\fi
  2873.  \setbox\z@=\next@{#2}\Lc=\Leftness@\wdz@ \Rc=\wdz@ \advance\Rc-\Lc
  2874.  \Dc=\dp\z@ \advance\Dc\ht\z@ \Uc=\Upness@\Dc \advance\Dc-\Uc
  2875. % \setbox\z@=\next@{#2}\adjustLR@ \adjustUD@
  2876.  \Rp=\z@ \Lp=\Lc \Up=\Uc \advance\Up-\ht\z@ \Dp=-\Up        %?*[OBJ3]
  2877.  \the\toks@\toks@={}\setboxz@h{\kern\Rp \raise\Up\boxz@}%
  2878. %
  2879.  \ifdim\Rc=\z@ \ifdim\Uc=\z@ \ifdim\Lc=\z@ \ifdim\Dc=\z@
  2880.      \Edgec={\zeroEdge}\fi\fi\fi\fi
  2881. %
  2882.  \dimen@=\Lc \advance\dimen@\Rc \wdz@=\dimen@ \ht\z@=\Uc \dp\z@=\Dc \boxz@
  2883.  \OBJECT@x}
  2884.  
  2885. \xydef@\adjustLR@{%
  2886.  \ifdim\wdz@=\z@ \Lc=\z@ \Rc=\z@ \dimen@=\Leftness@\p@
  2887.   \ifdim\dimen@<\z@ \Lc=\dimen@ \Rc=-\Lc
  2888.   \else\ifdim\dimen@>\p@ \Lc=\dimen@ \advance\Lc-\p@ \Rc=-\Lc \fi\fi
  2889.  \else \Lc=\Leftness@\wdz@ \Rc=\wdz@ \advance\Rc-\Lc \fi }
  2890.  
  2891. \xydef@\adjustUD@{\dimen@=\ht\z@ \advance\dimen@\dp\z@
  2892.  \ifdim\dimen@=\z@ \Uc=\z@ \Dc=\z@ \dimen@=\Upness@\p@
  2893.   \ifdim\dimen@<\z@ \Uc=\dimen@ \Dc=-\Lc
  2894.   \else\ifdim\dimen@>\p@ \Uc=\dimen@ \advance\Uc-\p@ \Dc=-\Lc \fi\fi
  2895.  \else \Dc=\dimen@ \Uc=\Upness@\dimen@ \advance\Dc-\Uc \fi }
  2896. \DOCMODE)
  2897.  
  2898.     As an optimisation |\OBJECT@@| sets the edge type of all zero-sized
  2899.     objects to |\zeroEdge|.
  2900.  
  2901.     |\OBJECT@x| cleans up the object by ensuring that it defines all the
  2902.     required methods: Essentially it terminates the box with the sequence
  2903.     ``|}| |\def\Drop@@{|\dots|}| |\def\Connect@@{|\dots|}| |\Dc=|\dots\
  2904.     |\Uc=|\dots\ |\Lc=|\dots\ |\Rc=|\dots\ | \Invisible@|\dots
  2905.     |\Hidden@|\dots\ |\def\Leftness@{|\dots|}| |\def\Upness@{|\dots|}|''
  2906.     where each \dots\ is set to the method defined within the object
  2907.     creation environment (started with |\hbox{| in |\OBJECT@@| or
  2908.     possibly elsewhere).  We use rather heavy expansion hacking with
  2909.     |\toks@| to create the sequence so please look the other
  2910.     way\dots\smiley
  2911.  
  2912. \DOCMODE(
  2913. \xydef@\OBJECT@x{\toks@={\egroup\def\Drop@@}%
  2914.  \expandafter\addtotoks@\expandafter{\expandafter{\Drop@@}\def\Connect@@}%
  2915.  \expandafter\addtotoks@\expandafter{\expandafter{\Connect@@}}%
  2916.  \edef\tmp@{\Dc=\the\Dc \Uc=\the\Uc \Lc=\the\Lc \Rc=\the\Rc
  2917.   \Edgec={\expandafter\noexpand\the\Edgec}%
  2918.   \ifInvisible@\noexpand\Invisible@true\else\noexpand\Invisible@false\fi
  2919.   \ifHidden@\noexpand\Hidden@true\else\noexpand\Hidden@false\fi
  2920.   \def\noexpand\Leftness@{\Leftness@}\def\noexpand\Upness@{\Upness@}}%
  2921.  \expandafter\addtotoks@\expandafter{\tmp@}\the\toks@}
  2922. \DOCMODE)
  2923.  
  2924. \paragraph*{Methods:}
  2925. ??w[object methods]
  2926.  
  2927.     In addition to the ``current object properties'' for $c$
  2928.     (\cf~??[basics.state]) the following methods should be set up by
  2929.     all objects:
  2930.  
  2931. \begin{defs}
  2932.  |\Invisible@true| or |\Invisible@false| & whether object is ??!^[invisible]\cr
  2933.  |\Hidden@true| or |\Hidden@false| & whether object is ??!^[hidden]\cr
  2934.  |\def\Leftness@{|<factor>|}| & the desired $L/(L+R)$\cr
  2935.  |\def\Upness@{|<factor>|}| & the desired $U/(D+U)$\cr
  2936.  |\def\Drop@@{|\dots|}| & code that outputs the object, assuming |\boxz@| is
  2937.     of zero size and has the object displaced $|<|X|,|Y|>|$
  2938.     inside---usually just |\def|'d to |\boxz@|\cr
  2939.  |\def\Connect@@{|\dots|}| & code that builds a connection from $p$ to $c$,
  2940.     assuming |\last|\-|object|\-|box@| contains the object\cr
  2941. \end{defs}
  2942.  
  2943.     It is important to |\def| and not |\let| the last four methods since
  2944.     the \TeX\-nique used in |\OBJECT@x| (and elsewhere) of passing them
  2945.     to surrounding scopes depends on it.  The |\Connect@@| method should
  2946.     in turn setup several submethods as described in detail in
  2947.     ??[algo.connection].
  2948.  
  2949.     Suitable defaults are set up by |\OBJECT@@| above which is why any
  2950.     box generating command can be used to construct objects as explained
  2951.     in note ??[build default] below.
  2952.  
  2953.     Here are the declarations:
  2954.  
  2955. \DOCMODE(
  2956. \xynew@{if}\ifInvisible@
  2957. \xynew@{if}\ifHidden@
  2958.  
  2959. \xydef@\Leftness@{}
  2960. \xydef@\Upness@{}
  2961. \xydef@\Drop@@{\boxz@}
  2962. \xydef@\Connect@@{}
  2963. \DOCMODE)
  2964.  
  2965. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2966.  
  2967. \begin{notes}
  2968. %
  2969. \note??=[build default]
  2970. %
  2971.     A default <object> is built using |\object|\-|box| |{|<text>|}|.
  2972.     |\object|\-|box| is initially defined as 
  2973. %
  2974. \begin{code}
  2975. \def\objectbox#1{%
  2976.  \hbox{$\objectstyle{#1}$}}
  2977. \let\objectstyle=\displaystyle
  2978. \end{code}
  2979. \displaycode
  2980. %
  2981.     but may be redefined by options or the user.  The <text> should thus
  2982.     be in the mode required by the |\objectbox| command---with the
  2983.     default |\objectbox| it should be in math mode.
  2984.  
  2985. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2986.     Actually it is
  2987.  
  2988. \DOCMODE(
  2989. \xydef@\objectbox#1{\hbox{$\m@th\objectstyle{#1}$}}
  2990. \xylet@\objectstyle=\textstyle
  2991. \DOCMODE)
  2992.  
  2993. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2994.  
  2995. \note??=[build box]
  2996. %
  2997.     An <object> built from a \TeX\ box with dimensions $w*(h+d)$ will
  2998.     have $L_c=R_c=w/2$, $H_c=D_c=(h+d)/2$, thus initially be equipped
  2999.     with the adjustment |!C| (see note~??[shifted]).  In particular: in
  3000.     order to get the reference point on the (center of) the base line of
  3001.     the original <\TeX~box> then you should use the <modifier> |!|; to
  3002.     get the reference point identical to the \TeX\ reference point use
  3003.     the modifier |!!L|.
  3004.  
  3005.     \TeX\-nical remark: Any macro that expands to something that starts
  3006.     with a <box> may be used as a <\TeX~box> here.
  3007.  
  3008. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3009.     This is done by the parsing above.
  3010. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3011.  
  3012. \note??=[finished object box]
  3013. %
  3014.     Takes an object and constructs it, building a box; it is then
  3015.     processed according to the preceeding modifiers.  This form makes it
  3016.     possible to use any <object> as a \TeX\ box (even outside of
  3017.     \XY-pictures) because a finished object is always also a box.
  3018.  
  3019. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3020.  
  3021.     This macro is the main entry point to the <object> parser.
  3022.  
  3023. \DOCMODE(
  3024. \xydef@\object{\hbox\bgroup\object@}
  3025.  
  3026. \xydef@\object@{%
  3027.  \edef\next@{={\DirectionfromtheDirection@}}\expandafter\toks@\next@
  3028.  \plainxy@ \xyFN@\OBJECT@}
  3029. \DOCMODE)
  3030.  
  3031.     The initial value of |\toks@| <modifier> list is explained in
  3032.     note~??[direction] below.
  3033.  
  3034. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3035.  
  3036. \note??=[composite object box]
  3037. %
  3038.     Several <object>s can be combined into a single object using the
  3039.     special command |\composite| with a list of the desired objects
  3040.     separated with |*|s as the argument.  The resulting box (and object)
  3041.     is the least rectangle enclosing all the included objects.
  3042.  
  3043. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3044.  
  3045.     First we collect all the objects smash on top of each other in box0
  3046.     while we maintain the maximal extents in $(DULR)_p$.  Then we reset
  3047.     box0 to contain the same but with the right spacing around.
  3048.  
  3049. \DOCMODE(
  3050. \xydef@\composite#1#{\hbox\bgroup\composite@{#1}}
  3051.  
  3052. \xydef@\composite@#1#2{%
  3053.  \DN@{#1}\ifx\next@\empty\else\xywarning@{no variants of
  3054.     \string\composite\space allowed}\fi
  3055.  \global\setbox9=\hbox\bgroup
  3056.   \Dp=-\maxdimen \Up=-\maxdimen \Lp=-\maxdimen \Rp=-\maxdimen
  3057.   \xyFN@\composite@i#2@}
  3058.  
  3059. \xydef@\composite@i{%
  3060.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@i}%gobble spaces
  3061.  \else\ifx *\next \DN@ *{\xyFN@\composite@i}%
  3062.  \else\ifx @\next \DN@ @{\composite@x}%
  3063.   \xyerror@{<composite> object expected}{}\czeroEdge@
  3064.  \else \DN@{\composite@ii}\fi\fi\fi \next@}
  3065.  
  3066. \xydef@\composite@ii#1#{\composite@iii{#1}}
  3067.  
  3068. \xydef@\composite@iii#1#2{%
  3069.  \setbox\z@=\object#1{#2}%
  3070.  \ifInvisible@ \setboxz@h{}%
  3071.  \else \setboxz@h{\kern-\Lc \boxz@}\ht\z@=\z@ \dp\z@=\z@ \wd\z@=\z@ {\Drop@@}\fi
  3072.  \ifHidden@\else
  3073.   \ifdim\Up<\Uc \Up=\Uc \fi \ifdim\Dp<\Dc \Dp=\Dc \fi
  3074.   \ifdim\Rp<\Rc \Rp=\Rc \fi \ifdim\Lp<\Lc \Lp=\Lc \fi
  3075.  \fi
  3076.  \xyFN@\composite@iv}
  3077.  
  3078. \xydef@\composite@iv{%
  3079.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\composite@iv}%gobble spaces
  3080.  \else \ifx @\next \DN@ @{\composite@x}%
  3081.  \else \let\next@=\composite@i \fi\fi \next@}
  3082.  
  3083. \xydef@\composite@x{%
  3084.  \edef\tmp@{\egroup \Dc=\the\Dp \Uc=\the\Up \Lc=\the\Lp \Rc=\the\Rp}\tmp@
  3085.  \setboxz@h{\kern\Lc\box9}\ht\z@=\Uc \dp\z@=\Dc
  3086.  \dimen@=\Lc \advance\dimen@\Rc \wdz@=\dimen@
  3087.  \Edgec={\rectangleEdge}\computeLeftUpness@ \boxz@
  3088.  \OBJECT@x}
  3089.  
  3090. \xydef@\computeLeftUpness@{%
  3091.  \dimen@=\Lc \advance\dimen@\Rc
  3092.  \ifdim\dimen@=\z@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
  3093.   \ifdim\Lc=\z@\else
  3094.    \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edgec}%
  3095.    \ifx\next@\nextii@\Edgec={\rectangleEdge}\fi\fi
  3096.  \else \quotient@\Leftness@\Lc\dimen@ \fi
  3097.  \dimen@=\Uc \advance\dimen@\Dc 
  3098.  \ifdim\dimen@=\z@ \def\Connect@@{\straight@{\dottedSpread@\jot}}%
  3099.   \ifdim\Uc=\z@\else
  3100.    \DN@{\zeroEdge}\expandafter\DNii@\expandafter{\the\Edgec}%
  3101.    \ifx\next@\nextii@\Edgec={\rectangleEdge}\fi\fi
  3102.  \else \quotient@\Upness@\Uc\dimen@ \fi}
  3103. \DOCMODE)
  3104.  
  3105. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3106.  
  3107. \note ??=[entire \XY-picture as object]
  3108. %
  3109.     Take an entire \XY-picture and wrap it up as a box as described
  3110.     in~\S??[basics.pos].  Makes nesting of \XY-pictures possible: the
  3111.     inner picture will have its own zero point which will be its
  3112.     reference point "in" the outer picture when it is placed there.
  3113.  
  3114. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3115.  
  3116.     This is simple exploiting the fact that |\endxy| actually sets up the
  3117.     extents of the `object':
  3118.  
  3119. \DOCMODE(
  3120. \xydef@\xybox#1{\xy#1\endxy \Edgec={\rectangleEdge}\computeLeftUpness@}
  3121. \DOCMODE)
  3122.  
  3123. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3124.  
  3125. \note??=[shifted]
  3126. %
  3127.     An object is "shifted" a <vector> by moving the point inside it which
  3128.     will be used as the reference point.  This effectively pushes the
  3129.     object the same amount in the opposite direction.
  3130.  
  3131. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3132.  
  3133.     Shifting uses the special value of $R_p$ and $U_p$ used while
  3134.     evalutaing the <modifier>s.  The fact that shifts like |!C| refer to
  3135.     the initial object's size means that we should parse the <vector>
  3136.     such that its actions happen at modification time\dots hence
  3137.     |\xytotoks@| is used to delay execution.
  3138.  
  3139. \DOCMODE(
  3140. \xydef@\OBJECT@shift{%
  3141.  \let\xy@=\xytotoks@ \afterVECTORorEMPTY
  3142.   {\OBJECT@shift@}%
  3143.   {\addtotoks@{\Xc=-\Lc \advance\Xc\Rp \advance\Xc\Lp \Yc=\Up}\OBJECT@shift@}}
  3144.  
  3145. \xydef@\OBJECT@shift@{%
  3146.  \addtotoks@{\advance\Up-\Yc
  3147.   \advance\Lc\Xc \advance\Rc-\Xc \advance\Dc\Yc \advance\Uc-\Yc
  3148.   \computeLeftUpness@}%
  3149.  \let\xy@=\oxy@
  3150.  \xyFN@\OBJECT@}
  3151. \DOCMODE)
  3152.  
  3153. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3154.  
  3155. \begin{exercise}
  3156.     What is the difference between the <pos>itions |0*{a}!DR| and
  3157.     |0*!DR{a}|?
  3158. \answertext{The first typesets ``$a$'' centered around |0| and then moves $c$
  3159.     to the lower right corner, the second typesets ``$a$'' above the |0|
  3160.     point and does not change $c$.  With a ``$+$'' at |0| they look like
  3161.     this: $\vcenter{\xy*{+}*{a}!DR\endxy}$ and
  3162.     $\vcenter{\xy*{+}*!DR{a}\endxy}$.}%
  3163. \end{exercise}
  3164.  
  3165. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3166.  
  3167. \note??=[<object> size]??=[change size]??=[<size>]??=[default size]
  3168. %
  3169.     A <size> is a pair $|<|W|,|H|>|$ of the width and height of a
  3170.     rectangle.  When given as a <vector> these are just the vector
  3171.     coordinates, \ie, the <vector> starts in the lower left corner and
  3172.     ends in the upper right corner.  The posible <add op>erations that
  3173.     can be performed are described in the following table.
  3174. $$
  3175. \begin{array}{\otherbar c\otherbar l\otherbar}
  3176. \hline
  3177.  \hbox{<add op>} & \hbox{description} \\
  3178. \hline
  3179.  |+| & \hbox{grow} \\
  3180.  |-| & \hbox{shrink} \\
  3181.  |=| & \hbox{set to} \\
  3182.  |+=| & \hbox{grow to at least} \\
  3183.  |-=| & \hbox{shrink to at most} \\
  3184. \hline
  3185. \end{array}
  3186. $$
  3187.     In each case the <vector> may be omitted which invokes the ``default
  3188.     size'' for the particular <add op>:
  3189. $$
  3190. \begin{array}{\otherbar c\otherbar l\otherbar}
  3191. \hline
  3192.  \hbox{<add op>} & \hbox{default}\\
  3193. \hline
  3194.  |+|  & |+<|2*"objectmargin"|>| \\
  3195.  |-|  & |-<|2*"objectmargin"|>| \\
  3196.  |=|  & |=<|"objectwidth"|,|"objectheight"|>| \\
  3197.  |+=| & |+=<|\max(L_c+R_c,D_c+U_c)|>| \\
  3198.  |-=| & |-=<|\min(L_c+R_c,D_c+U_c)|>| \\
  3199. \hline
  3200. \end{array}
  3201. $$
  3202.     The defaults for the first three are set with the commands
  3203. %
  3204. \begin{defs1}
  3205.  |\objectmargin| <add op> |{|<dimen>|}| \cr
  3206.  |\objectwidth| <add op> |{|<dimen>|}|    \cr
  3207.  |\objectheight| <add op> |{|<dimen>|}| \cr
  3208. \end{defs1}
  3209. \noindent\unskip
  3210. %
  3211.     where <add op> is interpreted in the same way as above.
  3212.  
  3213. \DOCMODE(
  3214. \xylet@\objectmargin@=\jot
  3215. \xylet@\objectwidth@=\z@
  3216. \xylet@\objectheight@=\z@
  3217.  
  3218. \xydef@\objectmargin{\afterADDOP{\Addop@@\objectmargin@}}
  3219. \xydef@\objectwidth{\afterADDOP{\Addop@@\objectwidth@}}
  3220. \xydef@\objectheight{\afterADDOP{\Addop@@\objectheight@}}
  3221. \DOCMODE)
  3222.  
  3223.     The defaults for |+=|/|-=| are such that the resulting object will be
  3224.     the smallest containing/largest contained square.
  3225.  
  3226. \begin{exercise}
  3227.     How are the objects typeset by the <pos>itions ``|*+UR{\sum}|'' and
  3228.     ``|*+DL{\sum}|'' enlarged?
  3229. \answertext{They have the outlines
  3230.  $$\xy*+UR{\sum}*\frm{-}*{+}\endxy
  3231.    \quad\text{and}\quad
  3232.    \xy*+DL{\sum}*\frm{-}*{+}\endxy$$ 
  3233.     because the first is enlarged by the positive offset to the upper
  3234.     right corner and the second by the negative offset to the lower left
  3235.     corner.}
  3236. \end{exercise}
  3237.  
  3238.     \BUG: Currently changing the size of a circular object is buggy---it
  3239.     is changed as if it is a rectangle and then the change to the $R$
  3240.     parameter affects the circle.  This should be fixed probably by a
  3241.     generalisation of the |o| shape to be ovals or ellipses with
  3242.     horizontal/vertical axes.
  3243.  
  3244. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3245.  
  3246.     The three cases distinguished by the parsing above are handled
  3247.     similarly: they insert the parsed/default vector into $X,Y$ in the
  3248.     modifications and then perform the operation at that time using the
  3249.     |\xytotoks@| trick described in note~??[shifted]:
  3250.  
  3251. \DOCMODE(
  3252. \xydef@\OBJECT@change#1#2{%
  3253.  \afterADDOP{%
  3254.   \addEQ@\ifx \next
  3255.    \addtotoks@{\Xc=\Dc \advance\Xc\Uc \Yc=\Lc \advance\Yc\Rc}%
  3256.   \else
  3257.    \addtotoks@{\Xc=\objectmargin@ \advance\Xc\Xc \Yc=\Xc}%
  3258.   \fi
  3259.   \let\xy@=\xytotoks@ 
  3260.   \afterVECTORorEMPTY{\OBJECT@change@#1#2}{\OBJECT@change@#1#2}}}
  3261.  
  3262. \xydef@\OBJECT@set{%
  3263.  \afterADDOP{%
  3264.   \let\xy@=\xytotoks@ \afterVECTORorEMPTY
  3265.    {\OBJECT@change@+=}%
  3266.    {\addtotoks@{\Xc=\objectwidth@ \Yc=\objectheight@}\OBJECT@change@+=}}}
  3267. \DOCMODE)
  3268.  
  3269.     The real work is done by the following command: a hack using
  3270.     expansion tricks to make use of the |\Addop@@| known now on the
  3271.     values in $X,Y$ at modification time.
  3272.  
  3273. \DOCMODE(
  3274. \xydef@\OBJECT@change@#1#2{%
  3275.  \addtotoks@{\advance\Rc\Lc \advance\Rp-\Lc \let\tmp@=\Rc}%
  3276.  \expandafter\addtotoks@\expandafter{\Addop@@\tmp@{#1\Xc}\Rc=\tmp@
  3277.   \Lc=\Leftness@\Rc \advance\Rp\Lc \advance\Rc-\Lc}%
  3278.  \addtotoks@{\advance\Dc\Uc \let\tmp@=\Dc}%
  3279.  \expandafter\addtotoks@\expandafter{\Addop@@\tmp@{#1\Yc}\Dc=\tmp@
  3280.   \Uc=\Upness@\Dc \advance\Dc-\Uc}%
  3281.  \let\xy@=\oxy@ \xyFN@\OBJECT@}
  3282. \DOCMODE)
  3283.  
  3284.     It is clearly crucial that |\Addop@@| expands to its action
  3285.     immediately!  Also note that enlarging changes the initial box offset
  3286.     in the horizontal direction only, \ie, $R_p$.
  3287.  
  3288. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3289.  
  3290.     Finally the code to interpret an <add op> used above: This
  3291.     simply parses it and creates a macro |\Addop@@| that takes a
  3292.     control sequence and a parameter <dimen> as arguments, and
  3293.     expands directly to commands that perform the <add op> of the
  3294.     <dimen> on the control sequence:
  3295. $$
  3296. \begin{array}{\otherbar c\otherbar l\otherbar}
  3297. \hline
  3298.  \hbox{<add op>} & \hbox{effect of |\Addop@@| "cs" $D$} \\
  3299. \hline
  3300.  |+| & "cs" \from "cs"+D \\
  3301.  |-| & "cs" \from "cs"-D \\
  3302.  |=| & "cs" \from D \\
  3303.  |+=| & "cs" \from \left\{
  3304.   \begin{array}{cc} D       & \hbox{if $D\le"cs"$} \\
  3305.             "cs"   & \hbox{if $D\gt"cs"$} \end{array}\right.
  3306.   \\[1pt]
  3307.  |-=| & "cs" \from \left\{
  3308.   \begin{array}{cc} D       & \hbox{if $D\ge"cs"$} \\
  3309.             "cs"   & \hbox{if $D\lt"cs"$} \end{array}\right.
  3310.   \\[1pt]
  3311. \hline
  3312. \end{array}
  3313. $$
  3314.     Furthermore |\afterADDOP| leaves the |\next| token set to |=| in the
  3315.     last three cases only (this is used to determine the right default
  3316.     value in the size changes above).
  3317.  
  3318.     The |\afterADDOP| macro is relatively simple because <add op>s don't
  3319.     nest:
  3320.  
  3321. \DOCMODE(
  3322. \xydef@\afterADDOP#1{\def\afterADDOP@{#1}\xyFN@\ADDOP@}
  3323.  
  3324. \xylet@\afterADDOP@=\empty
  3325.  
  3326. \xydef@\ADDOP@{%
  3327.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\ADDOP@}%gobble spaces
  3328.  \else\addPLUS@\ifx \next \addPLUS@\DN@{\xyFN@\ADDOP@plus}%
  3329.  \else\addDASH@\ifx \next \addDASH@\DN@{\xyFN@\ADDOP@minus}%
  3330.  \else\addEQ@\ifx \next
  3331.   \addEQ@\DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
  3332.  \else
  3333.   \DN@{\def\Addop@@{\Addop@0+=}\afterADDOP@}%
  3334.  \fi\fi\fi\fi \next@}
  3335.  
  3336. \xydef@\ADDOP@plus{%
  3337.  \addEQ@\ifx \next
  3338.   \addEQ@\DN@{\def\Addop@@{\Addop@0+<}\afterADDOP@}%
  3339.  \else
  3340.   \DN@{\def\Addop@@{\Addop@1+=}\afterADDOP@}%
  3341.  \fi \next@}
  3342.  
  3343. \xydef@\ADDOP@minus{%
  3344.  \addEQ@\ifx \next
  3345.   \addEQ@\DN@{\def\Addop@@{\Addop@0->}\afterADDOP@}%
  3346.  \else
  3347.   \DN@{\def\Addop@@{\Addop@1-=}\afterADDOP@}%
  3348.  \fi \next@}
  3349. \DOCMODE)
  3350.  
  3351.     The work is done by the general |\Addop@| |{|$f$|}| |{|$\pm_1$|}|
  3352.     |{|$\pm_2$|}| |{|"cs"|}| $D$ that defines
  3353. $$
  3354. "cs" \equiv \left\{
  3355.   \begin{array}{ll}
  3356.     f*"cs"~{\pm_1}~D& \hbox{if $\lnot ((f*"cs"~{\pm_1}~D)~{\pm_2}~D)$} \\
  3357.     "cs"        & \hbox{otherwise} \end{array}\right.
  3358. $$
  3359.     and also leaves the dimension in |\dimen@|.
  3360.  
  3361. \DOCMODE(
  3362. \xydef@\Addop@#1#2#3#4#5{%
  3363.  \dimen@=#4\relax \edef#4{\the\dimen@}%
  3364.  \dimen@=#1\dimen@ \advance\dimen@#2#5\relax
  3365.  \ifdim\dimen@#3#4\else \edef#4{\the\dimen@}\fi
  3366.  \ifx\xy@\xyinitial@\else \DN@##1{\xy@@{\edef#4{##1}}}%
  3367.   \expandafter\next@\expandafter{#4}\fi}
  3368. \DOCMODE)
  3369.  
  3370. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3371.  
  3372. \note??=[invisible]
  3373. %
  3374.     An "invisible" object will be treated completely normal except that
  3375.     it won't be typeset, \ie, \XY-pic will behave as if it was.
  3376.  
  3377. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3378.     This is handled by the |\ifInvisible@| conditional allocated with the
  3379.     methods.
  3380. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3381.  
  3382. \note??=[hidden]
  3383. %
  3384.     A "hidden" object will be typeset but hidden from \XY-pic in that it
  3385.     won't affect the size of the entire picture as discussed
  3386.     in~\S??[basics.pos].
  3387.  
  3388. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3389.     This is handled by the |\ifHidden@| conditional allocated with the
  3390.     methods.
  3391. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3392.  
  3393. \note??=[<shape>]
  3394. %
  3395.     Setting the "shape" of an object forces the shape of its edge to be
  3396.     as indicated: the kernel just provides the three shapes |[.]|, |[]|,
  3397.     and |[o]|, corresponding to the outlines
  3398. $$
  3399. \let\objectstyle=\scriptstyle
  3400. \xy*{*}\endxy
  3401. \quad
  3402. \text{,}
  3403. \quad
  3404. \xy(0,0).(-10,-4).(15,7)*\frm{-}="box"*{*}+0;
  3405.  "box"+L*{}**\dir{.}?*{L},
  3406.  "box"+R*{}**\dir{.}?*{R},
  3407.  "box"+D*{}**\dir{.}?*{D},
  3408.  "box"+U*{}**\dir{.}?*{U}
  3409. \endxy
  3410. \quad
  3411. \text{, and}
  3412. \quad
  3413. \xy*[o]=<40pt>{*}="box"*\cir{}+0;
  3414.  "box"+L*{}**\dir{.}?*{L},
  3415.  "box"+R*{}**\dir{.}?*{R},
  3416.  "box"+D*{}**\dir{.}?*{D},
  3417.  "box"+U*{}**\dir{.}?*{U}
  3418. \endxy
  3419. $$
  3420.     where the $*$ denotes the point of the reference position in the
  3421.     object (the first is a point).  Extensions can provide more shapes,
  3422.     however, all shapes set the extent dimensions $L$, $R$, $D$,
  3423.     and $U$.
  3424.  
  3425.     The default shape for objects is |[]| and for plain coordinates it is
  3426.     |[.]|.
  3427.  
  3428. \DOCMODE(
  3429. \xydef@\objectEdge{\rectangleEdge}
  3430. \DOCMODE)
  3431.  
  3432.     \NOTE: Extensions may add <shape> object <modifier>s of two kinds:
  3433.     either |[|<keyword>|]| or |[|<character> <argument>|]|.  Some of
  3434.     these <shape>s do other things than set the edge of the object.
  3435.  
  3436. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3437.  
  3438.     A ``simple shape'' is just a control sequence |\*shape@|<shape>|@|
  3439.     setting the appropriate edge.  When such a |[|<shape>|]| modifier is
  3440.     encountered then we expand this control sequence onto the modifier
  3441.     queue.
  3442.  
  3443. \DOCMODE(
  3444. \xydef@\OBJECT@shape#1{\DN@{*shape@#1@}%
  3445.  \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
  3446.  \ifx\next\relax \DN@{\OBJECT@shapei[#1]}%
  3447.  \else \DN@{\expandafter\addtotoks@\expandafter{\next}\xyFN@\OBJECT@}\fi
  3448.  \next@}
  3449.  
  3450. \xydefcsname@{*shape@@}{\the\Edgec4}
  3451. \xydefcsname@{*shape@o@}{\Edgec={\circleEdge}\Lc=\Rc \Uc=\Rc \Dc=\Rc}
  3452. \xydefcsname@{*shape@.@}{\czeroEdge@}
  3453. \DOCMODE)
  3454.  
  3455.     Add more simple shapes by defining more commands like these and
  3456.     proceed with coding the |\|\dots|Edge| command as described
  3457.     in~\S??[algo.edge].
  3458.  
  3459.     Alternatively it is a ``complex shape'' of which none are defined in
  3460.     the kernel but some options like more variation\dots  It is
  3461.     characterised by its first token and the rest of the contents of the
  3462.     |[]|s is the argument (remember: no |{}[]| characters!)
  3463.  
  3464. \DOCMODE(
  3465. \xydef@\OBJECT@shapei[#1#2]{\DN@{*shapechar@#1@}%
  3466.  \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
  3467.  \ifx\next\relax \DN@{[#1#2]}%
  3468.    \xywarning@{illegal [<shape>] ignored: \codeof\next@\space not defined}%
  3469.  \else \expandafter\addtotoks@\expandafter{\next{#2}}\fi
  3470.  \xyFN@\OBJECT@}
  3471. \DOCMODE)
  3472.  
  3473. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3474.  
  3475. \note??=[diagonal]??=[direction]??=[<direction>]
  3476. %
  3477.     Setting the current direction is simply pretending for the
  3478.     typesetting of the object (and the following <modifier>s) that some
  3479.     connection set it.
  3480.  
  3481. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3482.  
  3483.     The code just calls the general <direction> parser below:
  3484.  
  3485. \DOCMODE(
  3486. \xydef@\OBJECT@direction{\afterDIRECTIONorEMPTY{%
  3487.   \edef\next@{{\DirectionfromtheDirection@}}\expandafter\addtotoks@\next@
  3488.   \xyFN@\OBJECT@}%
  3489.  {\xyFN@\OBJECT@}}
  3490. \DOCMODE)
  3491.  
  3492.     Here is the <direction> parser: first the parts parsing the <diag>
  3493.     part then the parts parsing the <trailer> part:
  3494.  
  3495. \DOCMODE(
  3496. \xydef@\afterDIRECTIONorEMPTY#1#2{%
  3497.  \DN@##1{\def\afterDIRECTION@{\def\afterDIRECTION@{##1}%
  3498.   \ifDIRECTIONempty@\DN@{#2}\else\DN@{#1}\fi \next@}}%
  3499.  \expandafter\next@\expandafter{\afterDIRECTION@}%
  3500.  \xyFN@\DIRECTION@}
  3501.  
  3502. \xylet@\afterDIRECTION@=\empty
  3503. \xynew@{if}\ifDIRECTIONempty@
  3504.  
  3505. \xydef@\DIRECTION@{%
  3506.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\DIRECTION@}%gobble spaces
  3507.  \else\ifx v\next \DN@ v{\DIRECTION@v}%
  3508.  \else
  3509.   \DN@{\count@=8 %
  3510.    \afterDIAG{\ifnum\count@=8 \DN@{\DIRECTIONempty@true \xyFN@\DIRECTION@i}%
  3511.     \else \DN@{\xy@@{\dimen@=\xydashl@}\Directionfromdiag@}\fi \next@}}%
  3512.  \fi\fi \next@}
  3513. \DOCMODE)
  3514.  
  3515. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3516.  
  3517.     It is particularly easy to set absolute, <diag>onal directions:
  3518. $$
  3519. \xy *[o]\cir<1pc>{}="c",
  3520.   "c"; (-1,-1)**{},p+/4pc/ *+{|dl|=|ld|} **\dir{-}?>*\dir{>},
  3521.   "c"; ( 0,-1)**{},p+/4pc/ *+{|d|}     **\dir{-}?>*\dir{>},
  3522.   "c"; ( 1,-1)**{},p+/4pc/ *+{|dr|=|rd|} **\dir{-}?>*\dir{>},
  3523.   "c"; ( 1, 0)**{},p+/4pc/ *+{|r|}     **\dir{-}?>*\dir{>},
  3524.   "c"; ( 1, 1)**{},p+/4pc/ *+{|ur|=|ru|} **\dir{-}?>*\dir{>},
  3525.   "c"; ( 0, 1)**{},p+/4pc/ *+{|u|}     **\dir{-}?>*\dir{>},
  3526.   "c"; (-1, 1)**{},p+/4pc/ *+{|ul|=|lu|} **\dir{-}?>*\dir{>},
  3527.   "c"; (-1, 0)**{},p+/4pc/ *+{|l|}     **\dir{-}?>*\dir{>},
  3528. \endxy
  3529. $$
  3530.  
  3531. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3532.  
  3533.     <diag>onals are stored internally as
  3534. $$
  3535. \xy *\cir<1pc>{}="c",
  3536.   "c"; (-1,-1)**{},p+/3pc/ *+{|0|} **\dir{-}?>*\dir{>},
  3537.   "c"; ( 0,-1)**{},p+/3pc/ *+{|1|} **\dir{-}?>*\dir{>},
  3538.   "c"; ( 1,-1)**{},p+/3pc/ *+{|2|} **\dir{-}?>*\dir{>},
  3539.   "c"; ( 1, 0)**{},p+/3pc/ *+{|3|} **\dir{-}?>*\dir{>},
  3540.   "c"; ( 1, 1)**{},p+/3pc/ *+{|4|} **\dir{-}?>*\dir{>},
  3541.   "c"; ( 0, 1)**{},p+/3pc/ *+{|5|} **\dir{-}?>*\dir{>},
  3542.   "c"; (-1, 1)**{},p+/3pc/ *+{|6|} **\dir{-}?>*\dir{>},
  3543.   "c"; (-1, 0)**{},p+/3pc/ *+{|7|} **\dir{-}?>*\dir{>},
  3544. \endxy
  3545. $$
  3546.     Expanding |\afterDIAG{|<stuff>|}|<diag> will result in |\count@|
  3547.     being set to the <diag> code (not changed in case the <diag> is
  3548.     <empty>) before expanding <stuff>.
  3549.  
  3550. \DOCMODE(
  3551. \def\afterDIAG#1{\def\afterDIAG@{#1}\xyFN@\DIAG@}
  3552.  
  3553. \xydef@\DIAG@{%
  3554.  \ifx d\next \DN@ d{\count@=1 \xyFN@\DIAG@@}%
  3555.  \else\ifx r\next \DN@ r{\count@=3 \xyFN@\DIAG@@}%
  3556.  \else\ifx u\next \DN@ u{\count@=5 \xyFN@\DIAG@@}%
  3557.  \else\ifx l\next \DN@ l{\count@=7 \xyFN@\DIAG@@}%
  3558.  \else \let\next@=\afterDIAG@
  3559.  \fi\fi\fi\fi \next@}
  3560.  
  3561. \xydef@\DIAG@@{\ifcase\count@ \or
  3562. %\count@=1          3              5              7
  3563.  \DIAG@@@ l0r2\or\or \DIAG@@@ d2u4\or\or \DIAG@@@ r4l6\or\or \DIAG@@@ u6d0%
  3564.  \else\xybug@{impossible <diag> number}\fi
  3565.  \next@}
  3566.  
  3567. \xydef@\DIAG@@@#1#2#3#4{%
  3568.  \ifx #1\next \count@=#2\DN@#1{\afterDIAG@}%
  3569.  \else \ifx #3\next \count@=#4\DN@#3{\afterDIAG@}%
  3570.  \else \let\next@=\afterDIAG@ \fi\fi}
  3571. \DOCMODE)
  3572.  
  3573.     The action in case of a <diag> is simply to pick the right direction
  3574.     setup routine according to the encoding, getting the <diag> from
  3575.     |\count@| and the length of the $d$ vector from |\dimen@|:
  3576.  
  3577. \DOCMODE(
  3578. \xydef@\Directionfromdiag@{\ifcase\count@
  3579.      \xy@@{\dlDirection@\dimen@}%
  3580.  \or \xy@@{\dDirection@\dimen@}%
  3581.  \or \xy@@{\drDirection@\dimen@}%
  3582.  \or \xy@@{\rDirection@\dimen@}%
  3583.  \or \xy@@{\urDirection@\dimen@}%
  3584.  \or \xy@@{\uDirection@\dimen@}%
  3585.  \or \xy@@{\ulDirection@\dimen@}%
  3586.  \or \xy@@{\lDirection@\dimen@}%
  3587.  \or % 8 is legal and means change nothing
  3588.  \else\xybug@{impossible <diag>}\fi
  3589.  \DIRECTIONempty@false\xyFN@\DIRECTION@i}
  3590. \DOCMODE)
  3591.  
  3592. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3593.  
  3594.     Alternatively |v|<vector> sets the direction as if the connection
  3595.     from |0| to the <vector> had been typeset except that the "origin" is
  3596.     assumed zero such that directions $|v(|x|,|y|)|$ mean the natural
  3597.     thing, \ie, is the direction of the connection from |(0,0)| to
  3598.     $|(|x|,|y|)|$.  With the initial coordinate system this means that
  3599.     the directions |ur| and |v(1,1)| are identical.
  3600.  
  3601. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3602.  
  3603.     The action for a |v| reads a <vector> and sets the direction
  3604.     accordingly using some expansion hackery to propagate it out.  The
  3605.     "origin" is cleared locally to make |v(|$x$|,|$y$|)| behave as it
  3606.     should, \ie, use the direction of
  3607.  
  3608. \DOCMODE(
  3609. \xydef@\DIRECTION@v{\begingroup \xy@{v}{\Xorigin=\z@ \Yorigin=\z@}%
  3610.   \afterVECTORorEMPTY
  3611.    {\xy@@{\Xp=\z@ \Yp=\z@ \setupDirection@}%
  3612.     \edef\next@{\noexpand\xy@@\DirectionfromtheDirection@}%
  3613.     \expandafter\endgroup\next@ \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
  3614.    {\xyerror@{<vector> expected after v}{}\endgroup
  3615.     \DIRECTIONempty@false \xyFN@\DIRECTION@i}}
  3616. \DOCMODE)
  3617.  
  3618. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3619.  
  3620.     Once the initial direction is established as either the last one or
  3621.     an absolute one then the remainder of the direction is interpreted.
  3622.  
  3623.     Adding |_| and |^| denote the result of rotating the default
  3624.     direction a right angle in the positive and negative direction.
  3625.  
  3626.     A trailing |:|<vector> is like |v|<vector> but uses the
  3627.     <direction> to set up a standard square base such that |:(0,1)| and
  3628.     |:a(90)| mean the same as |^| and |_| is equivalent to |:(0,-1)| and
  3629.     |:a(-90)|.
  3630.  
  3631. \DOCMODE(
  3632. \xydef@\DIRECTION@i{%
  3633.  \ifx ^\next \DN@ ^{\xy@^{\aboveDirection@\xydashl@}%
  3634.    \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
  3635.  \else\ifx _\next \DN@ _{\xy@_{\belowDirection@\xydashl@}%
  3636.    \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
  3637.  \else\ifx :\next \DN@ :{\begingroup
  3638.    \xy@:{\Xorigin=\z@ \Yorigin=\z@
  3639.     \Xxbase=\dX \Yxbase=\dY \Xybase=-\dY \Yybase=\dX}%
  3640.    \afterVECTORorEMPTY
  3641.     {\xy@@{\Xp=\z@ \Yp=\z@ \setupDirection@}%
  3642.      \edef\next@{\noexpand\xy@@\DirectionfromtheDirection@}%
  3643.      \expandafter\endgroup\next@ \DIRECTIONempty@false \xyFN@\DIRECTION@i}%
  3644.     {\xyerror@{<vector> expected after \string:}{}\endgroup
  3645.      \DIRECTIONempty@false \xyFN@\DIRECTION@i}}%
  3646.  \else
  3647.   \let\next@=\afterDIRECTION@
  3648.  \fi\fi\fi \next@}
  3649. \DOCMODE)
  3650.  
  3651.     \TODO: Allow |:a(|<angle>|)|.
  3652.  
  3653. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3654.  
  3655. \begin{exercise}
  3656.     What is the effect of the <modifier>s |v/1pc/| and |v/-1pc/|?
  3657. \answertext{The first has no effect since the direction is set to be that of
  3658.     a vector in the current direction, however, the second reverses the
  3659.     current direction.}
  3660. \end{exercise}
  3661.  
  3662. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3663.  
  3664. \end{notes}
  3665.  
  3666. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3667.  
  3668.  
  3669.  
  3670. \section{Decorations}
  3671. ??=[decor]
  3672.  
  3673. \DOCMODE(
  3674. \message{decorations;}
  3675. \DOCMODE)
  3676.  
  3677.     <Decor>ations are actual \TeX\ macros that decorate the current
  3678.     picture in manners that depend on the state.  They are used "after"
  3679.     the <pos>ition either of the outer |\xy|\dots|\endxy| or inside
  3680.     |{|\dots|}|.  The possibilities are given in figure~??[f.decor] with
  3681.     notes below.
  3682.  
  3683. \begin{figure*}[tp]
  3684. \vss
  3685. \begin{syntax}
  3686.  ??w![<decor>]
  3687.   &\iss    & <command> <decor>
  3688.     & either there is a command\dots
  3689. \cr
  3690.   &\orr    & <empty>
  3691.     & \dots or there isn't.
  3692. \cr
  3693.  ??w![<command>]
  3694.   &\iss    & |\save| <pos>
  3695.     & save ??!^[state] for restoration by later |\restore|, then do <pos>
  3696. \cr
  3697.   &\orr    & |\restore|
  3698.     & restore ??!^[state] saved by matcing |\save|
  3699. \cr
  3700.   &\orr    & |\POS| <pos>
  3701.     & interpret <pos>
  3702. \cr
  3703.   &\orr    & |\afterPOS| |{| <decor> |}| <pos>
  3704.     & interpret <pos> and then perform <decor>
  3705. \cr
  3706.   &\orr    & |\drop| <object>
  3707.     & drop <object> as the <pos> |*| operation
  3708. \cr
  3709.   &\orr    & |\connect| <object>
  3710.     & connect with <object> as the <pos> |**| operation
  3711. \cr
  3712.   &\orr    & |\relax|
  3713.     & do nothing
  3714. \cr
  3715.   &\orr    & <\TeX\ commands>
  3716.     & any ??!^[\TeX\ commands] and user defined macros that neither
  3717.       generates output (watch out for spaces!) nor changes the grouping
  3718.       may be used
  3719. \cr
  3720.   &\orr    & |\xyverbose| \orr\ |\xytracing| \orr\ |\xyquiet| \kern-3pc
  3721.     & \kern3pc ??!^[tracing] commands
  3722. \cr
  3723.   &\orr    & |\xyignore| |{|<pos> <decor>|}|
  3724.     & ??!^[ignore] \XY-code
  3725. \cr
  3726.   &\orr    & |\xycompileto| |{|<name>|}| |{|<pos> <decor>|}| \kern-3pc
  3727.     & \kern3pc ??!^[compile] to file <name>|.xyc|
  3728. \cr
  3729. \end{syntax}
  3730. \caption{\protect<decor>ations.}
  3731. ??=[f.decor]
  3732. \vfill
  3733. \end{figure*}
  3734.  
  3735.     Most options add to the available <decor>, in particular the |v2|
  3736.     option loads many more since \XY-pic versions prior to 2.7 provided
  3737.     most features as <decor>.
  3738.  
  3739. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3740.  
  3741. \paragraph*{Simple decorations:}
  3742.  
  3743.     |\POS| and |\afterPOS| have already been defined; the following are
  3744.     just simple applications of previously defined commands:
  3745.  
  3746. \DOCMODE(
  3747. \xydef@\drop#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
  3748.  \xy@{\drop#1{##1}}{\expandafter\drop@\the\toks9}\ignorespaces}\next@}
  3749.  
  3750. \xydef@\connect#1#{\DN@##1{\xy@@ix@{{#1}{##1}}%
  3751.  \xy@{\connect#1{##1}}{\expandafter\connect@\the\toks9}\ignorespaces}\next@}
  3752. \DOCMODE)
  3753.  
  3754. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3755.  
  3756. \begin{notes}
  3757. %
  3758. \note??=[state]
  3759. %
  3760.     Saving and restoring allows `excursions' where lots of things are
  3761.     added to the picture without affecting the resulting \XY-pic state,
  3762.     \ie, $c$, $p$, and "base", and without requiring matching |{}|s.  The
  3763.     independence of |{}| is particularly useful in conjunction with the
  3764.     |\afterPOS| command, for example, the definition
  3765.  
  3766. \begin{code}
  3767. \def\ToPOS{\save\afterPOS{%
  3768.   \POS**{}?>*\dir2{>}**\dir2{-}
  3769.  \restore};p,}
  3770. \end{code}
  3771. \gdocode
  3772. \displaycode
  3773.  
  3774.     will make the code |\ToPOS| <pos> make a double arrow from the
  3775.     current object to the <pos> (computed relative to it) such that
  3776. %
  3777. \begin{code}
  3778. \xy *{A} \ToPOS +<10mm,2mm> \endxy
  3779. \end{code}
  3780. %
  3781.     \thecode\ will typeset the picture \docode.
  3782.  
  3783. \paragraph*{Note:}
  3784.     Saving this way in fact uses the same state as the |{}| `grouping',
  3785.     so the code $p_1$|,| |{|$p_2$|\save},| \dots\ |{\restore}| will have
  3786.     $c=p_1$ both at the \dots\ and at the end!
  3787.  
  3788. \DOCMODE(
  3789. \xydef@\save{\xy@\save\save@ \POS}
  3790.  
  3791. \xydef@\save@{\enter@{\cfromthec@ \pfromthep@ \basefromthebase@}}
  3792.  
  3793. \xydef@\restore{\xy@\restore\leave@ \ignorespaces}
  3794. \DOCMODE)
  3795.  
  3796. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3797.  
  3798. \note??=[\TeX\ commands]
  3799. %
  3800.     One very tempting kind of \TeX\ commands to perform as <decor> is
  3801.     arithmetic operations on the \XY-pic state.  This will work in simple
  3802.     \XY-pictures as described here but be warned: "it is not portable"
  3803.     because all \XY-pic execution is indirect, and this is used by
  3804.     several options in nontrivial ways.  Check the \TeX-nical
  3805.     documentation~\cite{R94:XY-picCSTC} for details about this!
  3806.  
  3807.     Macros that expand to <decor> will always do the same, though.
  3808.  
  3809. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3810.  
  3811.     \TeX\ hackers like the author may enjoy changing the \XY-pic state
  3812.     directly using <decor> of the form |\xy@{|<id>|}{|<code>|}|\dots
  3813.  
  3814. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3815.  
  3816. \note??=[tracing]
  3817. %
  3818.     |\xyverbose| will switch on a tracing of all the \XY-pic commands
  3819.     executed.  |\xytracing| traces even more: the entire \XY-pic state is
  3820.     printed after each modification.  |\xyquiet| restores default quiet
  3821.     operation.
  3822.  
  3823. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3824.  
  3825.     The trick is to replace the |\xy@| command such that it calls the
  3826.     `normal' one between writing out a trace message and the state.
  3827.  
  3828. \DOCMODE(
  3829. \xydef@\xyverbose{\xy@\xyverbose{\let\xy@=\xyverbose@
  3830.  \W@{XY: \string\xyverbose\xytracelineno@}}}
  3831.  
  3832. \xydef@\xyverbose@#1#2{%
  3833.  {\def\1{#1}\ifx\1\empty\else\W@{XY: \codeof\1\xytracelineno@}\fi}%
  3834.  \oxy@{#1}{#2}}
  3835.  
  3836. \xydef@\xytracing{\xy@\xytracing{\let\xy@=\xytracing@
  3837.  \W@{XY TRACE: \string\xytracing\xytracelineno@}\xystatus@:}}
  3838.  
  3839. \xydef@\xytracing@#1#2{{\def\1{#1}\def\2{#2}%
  3840.  \W@{XY TRACE: \codeof\1 {\codeof\2}\xytracelineno@}}\oxy@{#1}{#2}\xystatus@:}
  3841.  
  3842. \xydef@\xystatus@#1{%
  3843.  \W@{#1 c=<\the\Xc,\the\Yc> \expandafter\string\the\Edgec
  3844.     \string[\the\Lc+\the\Rc,\the\Dc+\the\Uc\string]}%
  3845.  \W@{#1 p=<\the\Xp,\the\Yp> \expandafter\string\the\Edgep
  3846.     \string[\the\Lp+\the\Rp,\the\Dp+\the\Up\string]}%
  3847.  \W@{#1 [d=<\the\dX,\the\dY>
  3848.     Direction=\the\Direction=\string(\cosDirection,\sinDirection\string)]
  3849.     S=\the\csp@}%
  3850.  \W@{#1 base = <\the\Xorigin,\the\Yorigin> +
  3851.     x\string*<\the\Xxbase,\the\Yxbase> +
  3852.     y\string*<\the\Xybase,\the\Yybase>}%
  3853.  \W@{#1 min/max = <\the\Xmin,\the\Ymin> / <\the\Xmax,\the\Ymax>}}
  3854.  
  3855. \xydef@\xyquiet{\xy@\xyverbose{\let\xy@=\oxy@
  3856.   \W@{XY: \string\xyverbose\xytracelineno@}}}
  3857. \DOCMODE)
  3858.  
  3859. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3860.  
  3861. \note??=[ignore]
  3862. %
  3863.     Ignoring means that the <pos> <decor> is still parsed the usual way
  3864.     but nothing is typeset and the \XY-pic state is not changed.
  3865.  
  3866. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3867.  
  3868.     We ignore in a group to ensure that nothing done inside `leaks' to
  3869.     the outside.
  3870.  
  3871. \DOCMODE(
  3872. \xydef@\xyignore#1{\xy@\xyignore{\xyignore@{#1}}\ignorespaces}
  3873.  
  3874. \xydef@\xyignore@#1{{\let\xy@=\xyeat@ \let\oxy@=\xy@ \POS#1\relax}}
  3875.  
  3876. \xydef@\xyeat@#1#2{}
  3877. \DOCMODE)
  3878.  
  3879. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3880.  
  3881. \note??=[compile]
  3882. %
  3883.     It is possible to save the commands to generate parts of an
  3884.     \XY-picture to a file such that subsequent typesetting of those parts
  3885.     is significantly faster: this is called "compiling".  The created
  3886.     file will be named <name>|.xyc| and contain code to check that the
  3887.     compiled code still corresponds to the <pos> <decor> as well as more
  3888.     efficient compiled code to redo it.  If the <pos> <decor> has changed
  3889.     then the compilation is redone and <name>|.xyc| recreated.
  3890.  
  3891.     \BUG: Currently you can only compile matrices (built with the matrix
  3892.     feature) where all entries are empty or start with something that is
  3893.     unexpandable.
  3894.  
  3895. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3896.  
  3897.     It is done by just writing all |\xy@|-commands to the file.  The file
  3898.     establishes the correct input mode through use of the appropriate
  3899.     commands itself.
  3900.  
  3901. \DOCMODE(
  3902. \xylet@\compilename@@=\empty
  3903. \xylet@\xyrecompile@@=\relax
  3904.  
  3905. \xydef@\xycompileto#1#2{\if\inxy@ \DN@{\xy@@{\nter@{}}}%
  3906.  \else \DN@{\xy \xy@@{\nter@\endxy}}\fi \next@
  3907.  \ifxysaving@ \xyerror@{Compilations can not be nested}{}\fi
  3908.  \DN@{#1}\edef\compilename@@{\codeof\next@}\DNii@{#2}%
  3909.  \expandafter\xyinputorelse@\expandafter{\compilename@@.xyc}%
  3910.   {\def\xyrecompile@@{compiling new}}%
  3911.  \ifx\xyrecompile@@\relax\else \expandafter\xyrecompile@ \fi \xy@@\leave@}
  3912. \DOCMODE)
  3913.  
  3914.     Recompilation is done by just writing all |\xy@|-commands to the
  3915.     file.  The file establishes the correct input mode and terminates
  3916.     itself; after it has been finished it is simply reread to actually
  3917.     get the drawing done in the document.
  3918.  
  3919. \DOCMODE(
  3920. \xydef@\xyrecompile@{%
  3921.  \message{(\xyrecompile@@\space\string`\compilename@@.xyc\string'}%
  3922.  \DN@{\immediate\openout\xywrite@=}\expandafter\next@\compilename@@.xyc
  3923.  \immediate\write\xywrite@{%
  3924.   \string\xycompiled{\compilename@@}%
  3925.    {\the\year/\the\month/\the\day\string:\the\time\xytracelineno@}%
  3926.    {Xy-pic \xyversion}\xycomment@}%
  3927.  \immediate\write\xywrite@{{\codeof\nextii@}\relax}%
  3928.  {\xysaving@ \expandafter\POS\nextii@ \relax}%
  3929.  \immediate\write\xywrite@{\string\xyendcompiled}%
  3930.  \immediate\closeout\xywrite@ \message{done)}%
  3931.  \expandafter\input\compilename@@.xyc }
  3932.  
  3933. \xydef@\xysaving@{\let\xy@=\xysave@ \let\oxy@=\xy@
  3934.  \let\xy@@ix@=\xysave@@toksix@ \xysaving@true}
  3935.  
  3936. \xynew@{if}\ifxysaving@ \xysaving@false
  3937.  
  3938. \xydef@\xysave@#1#2{{\DN@{\xy@{#1}{#2}}%
  3939.   \immediate\write\xywrite@{\codeof\next@\xycomment@}}}
  3940.  
  3941. \xydef@\xysave@@toksix@#1{{\DN@{\xy@@ix@{#1}}%
  3942.   \immediate\write\xywrite@{\codeof\next@\relax}}}
  3943.  
  3944. \xywarnifdefined\xycomment@
  3945. {\catcode`\%=12 \catcode`\(=1 \catcode`\)=2 \gdef\xycomment@(%)}
  3946. \DOCMODE)
  3947.  
  3948.     \HACK{1:} The |\ifxysaving@| can never be locally switched off!
  3949.     Anyway it is used to allow a gross hack avoiding building a queue in
  3950.     the matrix option that will generate too long lines!!
  3951.  
  3952.     \HACK{2:} |\xysave@@toksix@| is not doing the catcode jive because it
  3953.     can never be invoked while loading a file (knock, knock~\smiley~).
  3954.  
  3955.     The initial command in all |.xyc| files check that this is the right
  3956.     file and that neither the version of \XY-pic nor the user's code has
  3957.     changed:
  3958.  
  3959. \DOCMODE(
  3960. \xydef@\xycompiled#1#2#3#4{\DN@{#1}\edef\next@{\codeof\next@}%
  3961.  \ifx\next@\compilename@@\else
  3962.   \xywarning@{This file does not contain the result of
  3963.     \string\xycompileto{\compilename@@}{...}^^J%
  3964.     but of \string\xycompileto{\next@}}\fi
  3965.  \edef\next{Xy-pic \xyversion}\DN@{#3}\ifx\next\next@
  3966.   \DN@{#4}\ifx\next@\nextii@ \message{compiled #2}\xycatcodes
  3967.   \else \def\xyrecompile@@{source changed - recompiling}\xyendinput \fi
  3968.  \else \def\xyrecompile@@{XY-pic version changed - recompiling}\xyendinput \fi}
  3969.  
  3970. \xydef@\xyendcompiled{\let\xyrecompile@@=\relax \xyendinput}
  3971. \DOCMODE)
  3972.  
  3973. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3974.  
  3975. \end{notes}
  3976.  
  3977. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3978.  
  3979.  
  3980.  
  3981. \section{Kernel object library}
  3982. ??=[objectlib]
  3983.  
  3984. \DOCMODE(
  3985. \message{kernel objects:}
  3986. \DOCMODE)
  3987.  
  3988.     In this section we present the "library objects" provided with the
  3989.     kernel language---several options add library objects.  They fall
  3990.     into three types: Most of the kernel objects (including all those
  3991.     usually used with |**| to build connections) are "directionals",
  3992.     described in \S??[objectlib.directionals].  The remaining kernel
  3993.     library objects are "circles" of \S??[objectlib.circles] and "text"
  3994.     of \S??[objectlib.text].
  3995.  
  3996. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3997.  
  3998.  
  3999. \subsection{Directionals}
  4000. ??=[objectlib.directionals]
  4001.  
  4002. \DOCMODE(
  4003. \message{directionals,}
  4004. \DOCMODE)
  4005.  
  4006.     The kernel provides a selection of "directionals": objects that
  4007.     depend on the current direction.  They all take the form
  4008. %
  4009. \begin{defs1}
  4010. %
  4011.  |\dir|<dir> \cr
  4012. %
  4013. \end{defs1}
  4014. \noindent\unskip
  4015. %
  4016.     to typeset a particular <dir>ectional object.  All have the structure
  4017. %
  4018. \begin{defs1}
  4019. %
  4020.  <dir> \iss\ <variant>|{|<main>|}|  \cr
  4021. %
  4022. \end{defs1}
  4023. \noindent\unskip
  4024. %
  4025.     with <variant> being <empty> or one of the characters |^_23| and
  4026.     <main> some mnemonic code.
  4027.  
  4028.     We will classify the directionals primarily intended for building
  4029.     connections as "connectors" and those primarily intended for
  4030.     placement at connection ends or as markers as "tips".
  4031.  
  4032. \begin{figure*}[t]
  4033.  %
  4034.  \def\Dx#1#2{\hbox{\def\1{#1{#2}}\enspace\tt\string\dir\codeof\1}}
  4035.  %
  4036.  \def\DC#1#{\DCx{#1}}
  4037.  \def\DCx#1#2{ \Dx{#1}{#2} & \vcenter{\xy
  4038.    0*\cir<5pt>{} ; (16,5)*=<10pt>{}*\frm{-} **\dir#1{.} **h\dir#1{#2}
  4039.   \endxy}}
  4040.  %
  4041.  \def\DT#1#{\DTx{#1}}
  4042.  \def\DTx#1#2{\Dx{#1}{#2} & \vcenter{\xy
  4043.    -(4,2.5)*{} ; (4,0)*{} **{} ?>*\dir#1{#2} **\dir#1{.}
  4044.   \endxy}}
  4045.  %
  4046.  \def\Darray#1#2{{\let\\=\cr \tabskip=0pt plus 1fil %
  4047.   \halign to\hsize{&\hfil$##$&$##$\hfil\\
  4048.   \noalign{\hbox to\hsize{\hss#1\hss}\smallskip}#2\crcr}\bigskip}}
  4049. %
  4050. \Darray{??!^[Dummy]}{\hbox{\tt\string\dir\string{\string}}}
  4051. %
  4052. \Darray{??!^[Plain connectors]}{%
  4053.  \DC{-} &\DC2{-} &\DC3{-} \\
  4054.  \DC{.} &\DC2{.} &\DC3{.} \\
  4055.  \DC{~} &\DC2{~} &\DC3{~} \\
  4056.  \DC{--} &\DC2{--} &\DC3{--} \\
  4057.  \DC{~~} &\DC2{~~} &\DC3{~~} \\
  4058. }
  4059. \bigskip
  4060. \Darray{??!^[Plain tips]}{%
  4061.  \DT{>}     &\DT^{>} &\DT_{>} &\DT2{>} &\DT3{>} \\
  4062.  \DT{<}     &\DT^{<} &\DT_{<} &\DT2{<} &\DT3{<} \\
  4063.  \DT{|}     &\DT^{|} &\DT_{|} &\DT2{|} &\DT3{|} \\
  4064.  \DT{(}     &\DT^{(} &\DT_{(} \\
  4065.  \DT{)}     &\DT^{)} &\DT_{)} \\
  4066.  &     &\DT^{`} &\DT_{`} \\
  4067.  &     &\DT^{'} &\DT_{'} \\
  4068. }
  4069. \bigskip
  4070. \Darray{??!^[Constructed tips]}{%
  4071.  \DT{>>} &\DT^{>>} &\DT_{>>} &\DT2{>>} &\DT3{>>} \\
  4072.  \DT{<<} &\DT^{<<} &\DT_{<<} &\DT2{<<} &\DT3{<<} \\
  4073.  \DT{||} &\DT^{||} &\DT_{||} &\DT2{||} &\DT3{||} \\
  4074.  \DT{|-} &\DT^{|-} &\DT_{|-} &\DT2{|-} &\DT3{|-} \\
  4075.  \DT{>|} &\DT{>>|} &\DT{|<}  &\DT{|<<} \\
  4076.  \DT{+}     &\DT{x}   &\DT{/}   &\DT{*}   &\DT{o}     \\
  4077. }
  4078. \caption{Kernel library \protect<dir>ectionals}??=[f.dir]
  4079. \end{figure*}
  4080.  
  4081.     Figure~??[f.dir] shows all the <dir>ectionals defined by the kernel
  4082.     with notes below; each <main> type has a line showing the available
  4083.     <variant>s.  Notice that only some variants exist for each
  4084.     <dir>---when a nonexisting variant of a <dir> is requested then the
  4085.     <empty> variant is used silently.  Each is shown in either of the two
  4086.     forms available in each direction as applicable: connecting a
  4087.     $\bigcirc$ to a $\Box$ (typeset by |**\dir|<dir>) and as a tip at the
  4088.     end of a dotted connection of the same variant (\ie, typeset by the
  4089.     <pos> |**\dir|<variant>|{.}| |?>| |*\dir|<dir>).
  4090.  
  4091.     As a special case an entire <object> is allowed as a <dir> by
  4092.     starting it with a |*|: |\dir*| is equivalent to |\object|.
  4093.  
  4094. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4095.  
  4096. \paragraph*{Setup:}
  4097.  
  4098.     |\dir| starts an <object> and passes control to a `finisher' named
  4099.     |\dir|<variant>|{|<main>|}| otherwise to the one corresponding to an
  4100.     <empty> <variant>.  The kernel ones described here have in common
  4101.     that they make use of the generic |\straight@| defined
  4102.     in~\S??[algo.connection].
  4103.  
  4104. \DOCMODE(
  4105. \xydef@\dir{\hbox\bgroup\xyFN@\dir@i}
  4106.  
  4107. \xydef@\dir@i{\ifx *\next \DN@*{\object@}\else \let\next@=\dir@ii \fi \next@}
  4108.  
  4109. \xydef@\dir@ii#1#{\dir@{#1}}
  4110.  
  4111. \xydef@\dir@#1#2{\DN@{dir#1{#2}}%
  4112.  \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
  4113.  \ifx\next\relax \DN@{dir{#2}}%
  4114.   \expandafter\let\expandafter\next\csname\codeof\next@\endcsname
  4115.   \ifx\next\relax \DN@{\dir#1{#2}}%
  4116.    \xyerror@{illegal <dir>: \codeof\next@\space not defined}{}%
  4117.    \let\next=\no@ \fi\fi \next}
  4118. \DOCMODE)
  4119.  
  4120. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4121.  
  4122. \begin{notes}
  4123.  
  4124. \note??=[Dummy]
  4125.  
  4126.     You may use |\dir{}| for a ``dummy'' directional object (in fact this
  4127.     is used automatically by |**{}|).  This is useful for a uniform
  4128.     treatment of connections, \eg, making the |?| <pos> able to find a
  4129.     point on the straight line from $p$ to $c$ without actually
  4130.     typesetting anything.
  4131.  
  4132. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4133.  
  4134.     Uses an empty droppping, the |\no@@| connection.  All the variants
  4135.     are defined for optimisation reasons and it is also named |\dir{ }|
  4136.     to allow spurious spaces:
  4137.  
  4138. \DOCMODE(
  4139. \xydefcsname@{dir{}}{\no@}
  4140.  
  4141. \xyletcsnamecsname@{dir0{}}{dir{}}
  4142. \xyletcsnamecsname@{dir1{}}{dir{}}
  4143. \xyletcsnamecsname@{dir^{}}{dir{}}
  4144. \xyletcsnamecsname@{dir_{}}{dir{}}
  4145. \xyletcsnamecsname@{dir2{}}{dir{}}
  4146. \xyletcsnamecsname@{dir3{}}{dir{}}
  4147.  
  4148. \xyletcsnamecsname@{dir{ }}{dir{}}
  4149.  
  4150. \xydef@\no@{\egroup \czeroEdge@ \Invisible@false \Hidden@false
  4151.  \def\Leftness@{.5}\def\Upness@{.5}%
  4152.  \def\Drop@@{\setbox\z@=\copy\voidb@x}\def\Connect@@{\no@@}}
  4153. \DOCMODE)
  4154.  
  4155. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4156.  
  4157. \note??=[Plain connectors]
  4158.  
  4159.     The "plain connectors" group contains basic directionals that lend
  4160.     themself to simple connections.
  4161.  
  4162. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4163.  
  4164.     The bulk of the code is in fact in the description of these.  First
  4165.     each of the three types---lines, dots, and squiggles---then the code
  4166.     for doubling and tripling.
  4167.  
  4168. \paragraph*{Lines:}
  4169.  
  4170.     A single |\dir{-}| object is a dash in the current direction: build
  4171.     box with character $C$ of the semidirectional |\xydashfont|; use the
  4172.     characters natural width $w$ and construct a height/depth from $d =
  4173.     \abs{\sin(|\Direction|)}|em|$ (where |1em| is the dash length,
  4174.     \cf~|xydash10.mf|) as follows:
  4175. $$
  4176. \begin{array}{cccccc}
  4177.     C     & L & R & D & U & "flip if"  \\
  4178.    0\ldots30  & 0 & w & 0 & d & dY \lt 0 \\
  4179.   31\ldots63  & 0 & w & d & 0 & dY \gt 0 \\
  4180.   64\ldots95  & 0 & w & d & 0 & dX \lt 0 \\
  4181.   96\ldots127 & 0 & w & 0 & d & dX \lt 0 \\
  4182. \end{array}
  4183. $$
  4184.     where "flip" means shift the box opposite vertically and
  4185.     horizontally, \ie, $(L,R,D,U) := (R,L,U,D)$, and then lower the box
  4186.     $D-U$.
  4187.  
  4188.     "Procedure": (??_[line1])~Compute $d$, (??_[line2])~set $D,U$, and
  4189.     flip condition, (??_[line3])~build box to get $w,L,R$,
  4190.     (??_[line4])~dump box that is flipped if condition holds, and
  4191.     (??_[line5])~finally setup the required parameters properly.
  4192.  
  4193. \DOCMODE(
  4194. \xydefcsname@{dir1{-}}{\line@}
  4195. \xydefcsname@{dir2{-}}{\line@ \double@\xydashh@}
  4196. \xydefcsname@{dir3{-}}{\line@ \triple@\xydashh@}
  4197. \xyletcsnamecsname@{dir0{-}}{dir{}}
  4198. \xyletcsnamecsname@{dir{-}}{dir1{-}}
  4199. \xyletcsnamecsname@{dir{=}}{dir2{-}}
  4200.  
  4201. \xydef@\line@{\dimen@=\sdY\sinDirection\xydashl@        %?*[line1]
  4202.   \ifnum\SemiDirectionChar<31 \Dc=\z@ \Uc=\dimen@ \DN@{\dY<\z@}% %?*[line2]
  4203.   \else\ifnum\SemiDirectionChar<64 \Dc=\dimen@ \Uc=\z@ \DN@{\z@<\dY}%
  4204.   \else\ifnum\SemiDirectionChar<96 \Dc=\dimen@ \Uc=\z@ \DN@{\dX<\z@}%
  4205.   \else \Dc=\z@ \Uc=\dimen@ \DN@{\dX<\z@}\fi\fi\fi
  4206.   \setboxz@h{\line@@}\ht\z@=\Uc \dp\z@=\Dc            %?*[line3]
  4207.   \Lc=\z@ \Rc=\wdz@
  4208.   \ifdim\next@ \dimen@=\Rc \Rc=\Lc \Lc=\dimen@            %?*[line4]
  4209.    \dimen@=\Uc \Uc=\Dc \Dc=\dimen@ \advance\dimen@-\Uc
  4210.    \lower\dimen@\boxz@
  4211.   \else \boxz@ \fi
  4212.   \edef\tmp@{\egroup \Uc=\the\Uc \Dc=\the\Dc \Lc=\the\Lc \Rc=\the\Rc}% %?*[line5]
  4213.  \tmp@
  4214.  \Edgec={\rectangleEdge}\Invisible@false\Hidden@false
  4215.  \ifdim\z@<\Uc \def\Upness@{1}\else \def\Upness@{0}\fi
  4216.  \ifdim\z@<\Lc \def\Leftness@{1}\else \def\Leftness@{0}\fi
  4217.  \def\Drop@@{\boxz@}\def\Connect@@{\solid@}}
  4218.  
  4219. \xydef@\line@@{{\xydashfont\SemiDirectionChar\/}}
  4220. \DOCMODE)
  4221.  
  4222.     \BUG: |\line@| should allow the size of the object to be changed
  4223.     after typesetting---this should make |\Connect@@| do dashing.  Hm.
  4224.  
  4225.     As mentioned above a dash will `Connect' to make lines by using rules
  4226.     when strictly horizontal or vertical.  This is controlled by enabling
  4227.     or disabling the test |\ifjusthvtest@| discussed below.
  4228.  
  4229. \DOCMODE(
  4230. \xydef@\solid@{%
  4231.  \ifInvisible@ \DN@{\no@@}%
  4232.  \else \dimen@=\Yc \advance\dimen@-\Yp
  4233.    \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{\solidhrule@}%
  4234.  \else \dimen@=\Xc \advance\dimen@-\Xp
  4235.    \ifjusthvtest@.05pt>\ifdim\dimen@<\z@-\fi\dimen@ \DN@{\solidvrule@}%
  4236.  \else \DN@{\straight@\solidSpread@}\fi\fi\fi
  4237.  \next@}
  4238. \DOCMODE)
  4239.  
  4240.     Finally, we give the algorithm for `spreading' the dashes along a
  4241.     solid line: just add an extra dash so they always overlap
  4242.     (see~\S??[algo.connection] for a proper defintion of the requirements
  4243.     to spreading).
  4244.  
  4245. \DOCMODE(
  4246. \xydef@\solidSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi}
  4247. \DOCMODE)
  4248.  
  4249. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4250.  
  4251.     By default \XY-pic will typeset horizontal and vertical |\dir{-}|
  4252.     connections using \TeX\ rules.  Unfortunately rules is the feature of
  4253.     the DVI format most commonly handled wrong by DVI drivers.  Therefore
  4254.     \XY-pic provides the <decor>ations
  4255. %
  4256. \begin{defs1}
  4257. %
  4258.  |\NoRules| \cr
  4259.  |\UseRules| \cr
  4260. %
  4261. \end{defs1}
  4262. \noindent\unskip
  4263. %
  4264.     that will switch the use of such off and on.
  4265.  
  4266. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4267.  
  4268.     They simply redefine the conditional used to select typesetting
  4269.     with rules in |\solid@| above:
  4270.  
  4271. \DOCMODE(
  4272. \xylet@\ifjusthvtest@=\ifdim
  4273.  
  4274. \xydef@\NoRules{\let\ifjusthvtest@=\iffalse}
  4275. \xydef@\UseRules{\let\ifjusthvtest@=\ifdim}
  4276. \DOCMODE)
  4277.  
  4278.     The actual typesetting essentially means calling |\drop@| to box with
  4279.     a rule of the appropriate length and with line width set to that of
  4280.     |\xydashfont| (as stored in |\xydashw@|).
  4281.  
  4282. \DOCMODE(
  4283. \xydef@\solidvrule@{\no@@{%
  4284.   \ifdim\Yc<\Yp \dimen@=\Yc \Yc=\Yp \Yp=\dimen@ \advance\Yc-\Dp \advance\Yp\Uc
  4285.   \else \advance\Yc-\Dc \advance\Yp\Up \fi
  4286.   \advance\Xc-.5\xydashw@
  4287.  \setboxz@h{\kern\Xc \vrule width\xydashw@ height\Yc depth-\Yp}%
  4288.  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}}
  4289.  
  4290. \xydef@\solidhrule@{\no@@{%
  4291.   \ifdim\Xc<\Xp \advance\Xc\Rc \advance\Xp-\Lp
  4292.   \else \dimen@=\Xc \Xc=\Xp \Xp=\dimen@ \advance\Xc\Rp \advance\Xp-\Lc \fi
  4293.   \advance\Xp-\Xc \advance\Yc.5\xydashw@ \advance\Yp-.5\xydashw@
  4294.  \setboxz@h{\kern\Xc \vrule width\Xp height\Yc depth-\Yp}%
  4295.  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}}
  4296. \DOCMODE)
  4297.  
  4298. \paragraph*{Dots:}
  4299.  
  4300.     |\dir{.}| creates a very boring dot when used as an object but
  4301.     interesting dotted lines when connected with.  |\zerodot| should
  4302.     expand to a zerosized box with a dot (injtilaised to use
  4303.     |\zero|\-|dotbox@|); the object is built using |\pointlike@| <text>
  4304.     <spread-dimen> that we will use again later.
  4305.  
  4306. \DOCMODE(
  4307. \xydef@\zerodot{\copy\zerodotbox@}
  4308.  
  4309. \xydefcsname@{dir1{.}}{\point@}
  4310. \xydefcsname@{dir2{.}}{\point@ \double@\xydashh@}
  4311. \xydefcsname@{dir3{.}}{\point@ \triple@\xydashh@}
  4312. \xyletcsnamecsname@{dir0{.}}{dir{}}
  4313. \xyletcsnamecsname@{dir{.}}{dir1{.}}
  4314. \xyletcsnamecsname@{dir{:}}{dir2{.}}
  4315.  
  4316. \xydef@\point@{\pointlike@\zerodot\p@}
  4317.  
  4318. \xydef@\pointlike@#1#2{%
  4319.  \setboxz@h{#1}\wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@\egroup
  4320.  \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}\ctipEdge@
  4321.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@{#2}}}}
  4322. \DOCMODE)
  4323.  
  4324.     This is reflected by the rather complicated spreading routine:
  4325.     `Dotting' is the art of putting zero-sized objects together with
  4326.     equal distance independent of the chosen direction.  So we must
  4327.     recompute the number of segments $N$ (likely to be very big or
  4328.     ${-}1$) with trigonometrics; using "radius" for the individual dots
  4329.     this becomes
  4330. $$
  4331. \begin{array}{lc}
  4332.  ??_[dottedspread1]
  4333.     & A := \abs{\cos{|\Direction|}}*2*"radius"\\
  4334.     & B := \abs{\sin{|\Direction|}}*2*"radius"\\
  4335.  ??_[dottedspread2]
  4336.     & "Filler" := <box with the original filler centered...>\\
  4337.  ??_[dottedspread3]
  4338.     & |<\dX,\dY>| := |<\dX,\dY>| + |<\sdX|*A|,\sdY|*B|>|\\
  4339.     & |<|X|,|Y|>| := |<|X|,|Y|>| + |<\sdX|*A/2|,\sdY|*B/2|>|\\
  4340.  ??_[dottedspread4]
  4341.     & N := \floor{"if"~\abs{dX}\gt\abs{dY}
  4342.         ~"then" \abs{dX}/A else \abs{dY}/B} + 1
  4343. \end{array}
  4344. $$
  4345.     as realised below:
  4346.  
  4347. \DOCMODE(
  4348. \xydef@\dottedSpread@#1{\setupDirection@        %?*[dottedspread1]
  4349.  \dimen@=#1\relax \dimen@=2\dimen@
  4350.  \A@=\sdX\cosDirection\dimen@ \B@=\sdY\sinDirection\dimen@
  4351.  \global\setbox\lastobjectbox@=\hbox to\A@{\hss        %?*[dottedspread2]
  4352.   \kern.5\A@\box\lastobjectbox@\kern.5\A@\hss}%
  4353.  \dp\lastobjectbox@=.5\B@ \ht\lastobjectbox@=.5\B@
  4354.  \advance\dX\sdX\A@ \advance\dY\sdY\B@            %?*[dottedspread3]
  4355.  \advance\Xc\sdX.5\A@ \advance\Yc\sdY.5\B@
  4356.  \ifdim\sdY\dY<\sdX\dX \dimen@=\sdX\dX            %?*[dottedspread4]
  4357.   \ifdim\A@=\z@\else \divide\dimen@\A@ \fi \count@@=\dimen@
  4358.  \else\ifdim\z@=\sdY\dY\else
  4359.    \dimen@=\sdY\dY \ifdim\B@=\z@\else \divide\dimen@\B@ \fi \count@@=\dimen@
  4360.  \fi\fi \advance\count@@\@ne}
  4361. \DOCMODE)
  4362.  
  4363. \paragraph*{Squiggles:}
  4364.  
  4365.     These are just a lot of box maneuvering using the directional
  4366.     characters of |\xybsqlfont| (see~|xybsql10.mf| for details):
  4367.  
  4368. \DOCMODE(
  4369. \xydefcsname@{dir1{~}}{\squiggle@}
  4370. \xydefcsname@{dir2{~}}{\squiggle@ \double@\xybsqlh@}
  4371. \xydefcsname@{dir3{~}}{\squiggle@ \triple@\xybsqlh@}
  4372. \xyletcsnamecsname@{dir0{~}}{dir{}}
  4373. \xyletcsnamecsname@{dir{~}}{dir1{~}}
  4374.  
  4375. \xydef@\squiggle@{\xybsqlfont
  4376.   \dimen@=\sdX\cosDirection\xybsqll@ \advance\dimen@.1\p@
  4377.   \dimen@ii=\sdY\sinDirection\xybsqll@
  4378.   \kern\dimen@\squiggle@@
  4379.  \edef\tmp@{\egroup \Uc=\the\dimen@ii \Lc=\the\dimen@}\tmp@
  4380.  \wdz@=2\Lc \Rc=\Lc \ht\z@=\Uc    \Dc=\Uc \dp\z@=\Uc \Edgec={\rectangleEdge}%
  4381.  \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
  4382.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@\squiggledSpread@}}
  4383.  
  4384. \xydef@\squiggle@@{\DirectionChar \count@=\DirectionChar
  4385.  \advance\count@-64 \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}
  4386. \DOCMODE)
  4387.  
  4388.     The interesting bit is that they spread by not spreading, \ie, by
  4389.     centering between the endpoints---this means
  4390. $$
  4391. \begin{array}{ll}
  4392.  X := X - d/2, dX := dX - d
  4393.     &\hbox{where}~ d = |\sdX|(\abs{dX} - N*A + |.1pt|)\\
  4394.  Y := Y - d/2, dY := dY - d
  4395.     &\hbox{where}~ d = |\sdY|(\abs{dY} - N*B + |.1pt|)\\
  4396. \end{array}
  4397. $$
  4398.  
  4399. \DOCMODE(
  4400. \xydef@\squiggledSpread@{%
  4401.  \dimen@=\dX \advance\dimen@-\sdX\count@@\A@ \advance\dimen@\sdX.3\p@
  4402.  \advance\Xc-.5\dimen@ \advance\dX-\dimen@
  4403.  \dimen@=\dY \advance\dimen@-\sdY\count@@\B@ \advance\dimen@\sdY.3\p@
  4404.  \advance\Yc-.5\dimen@ \advance\dY-\dimen@}
  4405. \DOCMODE)
  4406.  
  4407. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4408.  
  4409. \paragraph*{Double and triple directionals:}
  4410.  
  4411. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4412.  
  4413.     As can be seen by the last two columns, these (and most of the other
  4414.     connectors) also exist in double and triple versions with a |2| or a
  4415.     |3| prepended to the name.  For convenience |\dir{=}| and |\dir{:}|
  4416.     are synonyms for |\dir2{-}| and |\dir2{.}|, respectively; similarly
  4417.     |\dir{==}| is a synonym for |\dir2{--}|.
  4418.  
  4419. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4420.  
  4421.     This is very simple, really: |\double@| and |\triple@| do the work by
  4422.     redefining the |\Drop@@| method to do its job twice and thrice.
  4423.  
  4424. \DOCMODE(
  4425. \xydef@\double@#1{\edef\Drop@@{\dimen@=#1\relax
  4426.   \dimen@=.5\dimen@ \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
  4427.   \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
  4428.   \setbox2=\hbox{\kern-\A@\raise-\B@\boxz@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 }}
  4429.  
  4430. \xydef@\triple@#1{\edef\Drop@@{\dimen@=#1\relax
  4431.   \A@=-\sinDirection\dimen@ \B@=\cosDirection\dimen@
  4432.   \setbox2=\hbox{\kern\A@\raise\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
  4433.   \setbox2=\hbox{\kern-\A@\raise-\B@\copy\z@}\dp2=\z@ \ht2=\z@ \wd2=\z@ \box2 %
  4434.   \dp\z@=\z@ \ht\z@=\z@ \wdz@=\z@ \boxz@}}
  4435. \DOCMODE)
  4436.  
  4437. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4438.  
  4439. \paragraph*{Dashing directionals:}
  4440.  
  4441.     First traditional dashing:
  4442.  
  4443. \DOCMODE(
  4444. \xydefcsname@{dir1{--}}{\dash@}
  4445. \xydefcsname@{dir2{--}}{\dash@ \double@\xydashh@}
  4446. \xydefcsname@{dir3{--}}{\dash@ \triple@\xydashh@}
  4447. \xyletcsnamecsname@{dir0{--}}{dir{}}
  4448. \xyletcsnamecsname@{dir{--}}{dir1{--}}
  4449. \xyletcsnamecsname@{dir{==}}{dir2{--}}
  4450.  
  4451. \xydef@\dash@{\line@ \wdz@=2\wdz@ \ht\z@=2\ht\z@ \dp\z@=2\dp\z@
  4452.  \multiply\Dc\tw@ \multiply\Uc\tw@ \multiply\Lc\tw@ \multiply\Rc\tw@
  4453.  \def\Connect@@{\straight@\dashedSpread@}}
  4454. \DOCMODE)
  4455.  
  4456.     Since the dashes should reach the endpoints we do this:
  4457. $$
  4458. \begin{array}{l}
  4459.  "if"~ N\gt 0 ~"then"~ N := N+1\\
  4460.  dX := dX + d/2 ~"where"~ d = |\sdX|A\\
  4461.  dY := dY + d/2 ~"where"~ d = |\sdY|B\\
  4462.  "if"~ dX\gt 0 ~"then"~ X := X + A/2\\
  4463.  Y := Y + |\sdY|A/2\\
  4464. \end{array}
  4465. $$
  4466. \DOCMODE(
  4467. \xydef@\dashedSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
  4468.  \advance\dX\sdX.5\A@ \advance\dY\sdY.5\B@
  4469.  \ifdim\z@<\dX \advance\Xc.5\A@ \fi \advance\Yc\sdY.5\B@}
  4470. \DOCMODE)
  4471.  
  4472.     Dashed dashing of squiggled lines are simpler since squiggles are
  4473.     symmetric:
  4474.  
  4475. \DOCMODE(
  4476. \xydefcsname@{dir1{~~}}{\dashsquiggle@}
  4477. \xydefcsname@{dir2{~~}}{\dashsquiggle@ \double@\xybsqlh@}
  4478. \xydefcsname@{dir3{~~}}{\dashsquiggle@ \triple@\xybsqlh@}
  4479. \xyletcsnamecsname@{dir0{~~}}{dir{}}
  4480. \xyletcsnamecsname@{dir{~~}}{dir1{~~}}
  4481.  
  4482. \xydef@\dashsquiggle@{\squiggle@
  4483.  \multiply\Dc\tw@ \multiply\Uc\tw@ \multiply\Lc\tw@ \multiply\Rc\tw@
  4484.  \dimen@=\Lc \advance\dimen@\Rc \wdz@=\dimen@ \ht\z@=\Uc \dp\z@=\Dc
  4485.  \def\Connect@@{\straight@\dashsquiggledSpread@}}
  4486. \DOCMODE)
  4487.  
  4488.     The spreading of squiggles is similarly simpler: we just shave $1/4$
  4489.     squiggle size of each end of the conection in order to eliminate the
  4490.     blank space at both ends:
  4491.  
  4492. \DOCMODE(
  4493. \xydef@\dashsquiggledSpread@{\ifnum\z@<\count@@ \advance\count@@\@ne \fi
  4494.  \advance\Xc.5\A@ \advance\dX.5\A@ \advance\Yc.25\B@ \advance\dY.5\B@}
  4495. \DOCMODE)
  4496.  
  4497.     Finally ``dashed dotting'' synonyms:
  4498.  
  4499. \DOCMODE(
  4500. \xyletcsnamecsname@{dir1{..}}{dir{.}}
  4501. \xyletcsnamecsname@{dir2{..}}{dir2{.}}
  4502. \xyletcsnamecsname@{dir3{..}}{dir3{.}}
  4503. \xyletcsnamecsname@{dir{..}}{dir1{.}}
  4504. \xyletcsnamecsname@{dir{::}}{dir2{.}}
  4505. \DOCMODE)
  4506.  
  4507. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4508.  
  4509. \note??=[Plain tips]
  4510.  
  4511.     The group of "plain tips" contains basic objects that are useful as
  4512.     markers and arrowheads making connections, so each is shown at the
  4513.     end of a dotted connection of the appropriate kind.
  4514.  
  4515.     They may also be used as connectors and will build dotted
  4516.     connections. \eg, |**\dir{>}| typesets
  4517. $$
  4518.  \xy 0*++{}; (10,3)*++{} **\dir{>} \endxy
  4519. $$
  4520.  
  4521. \begin{exercise}
  4522.     Typeset the following two $+$s and a tilted square:
  4523. \begin{code}
  4524. $$\xy
  4525.  *{+}; p+(6,3)*{+} **{} ?(1)
  4526.  *\dir{-}  *!/-5pt/^\dir{-}
  4527.  *^\dir{-} *!/^-5pt/\dir{-}
  4528. \endxy$$
  4529. \end{code}
  4530. \docode
  4531. %
  4532.     "Hint": the dash created by |\dir{-}| has the length |5pt|.
  4533. %
  4534. \answercode
  4535. \answertext{One way is}
  4536. \answertext\displaycode
  4537. \answertext{Thus we first create the two $+$s as $p$ and $c$ and connect them
  4538.     with the dummy connection |**{}| to setup the direction parameters.
  4539.     Then we move `on top of $c$' with |?(1)| and position the four sides
  4540.     of the square using |^| and |_| for local direction changes and
  4541.     |/|<dimen>|/| for skewing the resulting object by moving its
  4542.     reference point in the opposite direction.}%
  4543. \end{exercise}
  4544.  
  4545. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4546.  
  4547. \DOCMODE(
  4548. \xylet@\ctipEdge@=\czeroEdge@
  4549. \DOCMODE)
  4550.  
  4551.     \TODO: Change tips to have a tiny size of 2sp which may be taken as
  4552.     an indication that it is a tip (this can be used by some features,
  4553.     \eg, `arrow').
  4554.  
  4555. \paragraph*{Arrow heads:}
  4556.  
  4557.     The ones intended for single connections are just characters from
  4558.     |\xyatipfont| and |\xybtipfont|.
  4559.  
  4560. \DOCMODE(
  4561. \xydefcsname@{dir1{>}}{\tip@}
  4562. \xydefcsname@{dir^{>}}{\atip@}
  4563. \xydefcsname@{dir_{>}}{\btip@}
  4564. \xyletcsnamecsname@{dir0{>}}{dir{}}
  4565. \xyletcsnamecsname@{dir{>}}{dir1{>}}
  4566.  
  4567. \xydefcsname@{dir1{<}}{\reverseDirection@\tip@}
  4568. \xydefcsname@{dir^{<}}{\reverseDirection@\btip@}
  4569. \xydefcsname@{dir_{<}}{\reverseDirection@\atip@}
  4570. \xyletcsnamecsname@{dir0{<}}{dir{}}
  4571. \xyletcsnamecsname@{dir{<}}{dir1{<}}
  4572.  
  4573. \xydef@\tip@{\tip@x\tip@@}
  4574. \xydef@\atip@{\tip@x\atip@@}
  4575. \xydef@\btip@{\tip@x\btip@@}
  4576.  
  4577. \xydef@\tip@x#1{#1\egroup
  4578.  \ctipEdge@ \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
  4579.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
  4580.  
  4581. \xydef@\tip@@{\atip@@\btip@@}
  4582. \xydef@\atip@@{\xyatipfont\DirectionChar}
  4583. \xydef@\btip@@{\xybtipfont\DirectionChar}
  4584. \DOCMODE)
  4585.  
  4586.     Double and triple tips are realised by taking the two halfs and
  4587.     `wringing them apart'; as the naming indicates they are meant to be
  4588.     put at the end of |2|- and |3|-connections.  This is currently done
  4589.     the slightly hacky (but efficient) way of adding directly to
  4590.     |\DirectionChar|; maybe this should be using |\vDirection@|?
  4591.  
  4592. \DOCMODE(
  4593. \xydefcsname@{dir2{>}}{\Tip@}
  4594. \xydefcsname@{dir2{<}}{\reverseDirection@\Tip@}
  4595.  
  4596. \xydef@\Tip@{\kern2.5pt \vrule height2.5pt depth2.5pt width\z@
  4597.  \Tip@@ \kern2.5pt \egroup
  4598.  \Uc=2.5pt \Dc=2.5pt \Lc=2.5pt \Rc=2.5pt \Edgec={\circleEdge}%
  4599.  \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
  4600.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
  4601.  
  4602. \xydef@\Tip@@{\count@=\DirectionChar
  4603.  \advance\count@-4 \ifnum\count@<\z@ \advance\count@128 \fi
  4604.  \xyatipfont\char\count@
  4605.  \advance\count@ 8 \ifnum127<\count@ \advance\count@-128 \fi
  4606.  \xybtipfont\char\count@}
  4607.  
  4608. \xydefcsname@{dir3{>}}{\Ttip@}
  4609. \xydefcsname@{dir3{<}}{\reverseDirection@\Ttip@}
  4610.  
  4611. \xydef@\Ttip@{\kern3.2pt \vrule height3.2pt depth3.2pt width\z@
  4612.  \Ttip@@ \kern3.2pt \egroup
  4613.  \Uc=3.2pt \Dc=3.2pt \Lc=3.2pt \Rc=3.2pt \Edgec={\circleEdge}%
  4614.  \Invisible@false \Hidden@false \def\Leftness@{.5}\def\Upness@{.5}%
  4615.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@{\dottedSpread@\jot}}}
  4616.  
  4617. \xydef@\Ttip@@{%
  4618.  \setboxz@h\bgroup\reverseDirection@\line@ \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@
  4619.  \kern-\Lc \boxz@ \kern\Lc
  4620.  {\vDirection@(1,-.31)\xydashl@ \xyatipfont\char\DirectionChar}%
  4621.  {\vDirection@(1,+.31)\xydashl@ \xybtipfont\char\DirectionChar}}
  4622. \DOCMODE)
  4623.  
  4624. \paragraph*{Stopper:}
  4625.  
  4626.     |\dir{||}| makes a `stopper' using just the appropriate |\xydashfont|
  4627.     character rotated $90^\circ$ and centered; the |^| and |_| variants
  4628.     are just shifted appropriately and two are used to make the |2| and
  4629.     |3| variants longer.
  4630.  
  4631. \DOCMODE(
  4632. \xydefcsname@{dir1{|}}{\stopper@}
  4633. \xydefcsname@{dir^{|}}{\aboveDirection@\xydashl@
  4634.  \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
  4635. \xydefcsname@{dir_{|}}{\belowDirection@\xydashl@
  4636.  \shiftdir@\line@\z@ \pointlike@{}\xydashh@}
  4637. \xydefcsname@{dir2{|}}{\stopper@ \double@\xydashh@}
  4638. \xydefcsname@{dir3{|}}{\stopper@ \double@{2\xydashh@}}
  4639.  
  4640. \xyletcsnamecsname@{dir0{|}}{dir{}}
  4641. \xyletcsnamecsname@{dir{|}}{dir1{|}}
  4642.  
  4643. \xydef@\stopper@{\tip@x\stopper@@}
  4644.  
  4645. \xydef@\stopper@@{\setboxz@h{\count@=\SemiDirectionChar \advance\count@64 %
  4646.   \ifnum127<\count@ \advance\count@-128 \fi \xydashfont\char\count@\/}%
  4647.  \setboxz@h{\kern-.5\wdz@ \dimen@=\sdY\cosDirection\xydashl@   
  4648.   \ifnum\SemiDirectionChar=95 \dimen@=\sdX\sdY\dimen@ \fi
  4649.   \raise.5\dimen@\boxz@}%
  4650.  \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4651. \DOCMODE)
  4652.  
  4653. \paragraph*{Hooks:}
  4654.  
  4655.     These are halfcircles opening towards or opposite |\Direction| and
  4656.     fastened by their center or either endpoint.  Build by lots of box
  4657.     manipulation with the |\xybsqlfont| quarter circles\dots\smiley
  4658.  
  4659. \DOCMODE(
  4660. \xydefcsname@{dir1{(}}{\hook@}
  4661. \xydefcsname@{dir^{(}}{\ahook@}
  4662. \xydefcsname@{dir_{(}}{\bhook@}
  4663. \xyletcsnamecsname@{dir0{(}}{dir{}}
  4664. \xyletcsnamecsname@{dir{(}}{dir1{(}}
  4665.  
  4666. \xydefcsname@{dir1{)}}{\reverseDirection@\hook@}
  4667. \xydefcsname@{dir^{)}}{\reverseDirection@\bhook@}
  4668. \xydefcsname@{dir_{)}}{\reverseDirection@\ahook@}
  4669. \xyletcsnamecsname@{dir0{)}}{dir{}}
  4670. \xyletcsnamecsname@{dir{)}}{dir1{)}}
  4671.  
  4672. \xydef@\hook@{\tip@x\hook@@}
  4673. \xydef@\hook@@{\setboxz@h{\xybsqlfont
  4674.   \vDirection@(1,-1){.707107\xybsqll@}%
  4675.   \hbox{\DirectionChar
  4676.    \kern-\dY\raise\dX\hbox{\count@=\DirectionChar \advance\count@-32 %
  4677.     \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
  4678.  \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4679.  
  4680. \xydef@\ahook@{\tip@x\ahook@@}
  4681. \xydef@\ahook@@{\setboxz@h{\xybsqlfont
  4682.   \vDirection@(1,-1){.707107\xybsqll@}\kern-\dX
  4683.   \lower\dY\hbox{\DirectionChar
  4684.    \kern-\dY\raise\dX\hbox{\count@=\DirectionChar \advance\count@-32 %
  4685.     \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}}%
  4686.  \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4687.  
  4688. \xydef@\bhook@{\tip@x\bhook@@}
  4689. \xydef@\bhook@@{\setboxz@h{\xybsqlfont
  4690.   \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar
  4691.   \kern\dX\raise\dY\hbox{\count@=\DirectionChar \advance\count@-96 %
  4692.    \ifnum\count@<\z@ \advance\count@128 \fi \char\count@}}%
  4693.  \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4694. \DOCMODE)
  4695.  
  4696. \paragraph*{Quarter turns:}
  4697.  
  4698.     These are quarter circles fastened by their start or end point in
  4699.     |\Direction|.  Build by box manipulation of the |\xybsqlfont| quarter
  4700.     circles.  The intention is that the |`'| directionals are half the
  4701.     corresponding |()| directional.
  4702.  
  4703. \DOCMODE(
  4704. \xydefcsname@{dir^{'}}{\reverseDirection@\bturn@}
  4705. \xydefcsname@{dir_{'}}{\reverseDirection@\aturn@}
  4706.  
  4707. \xydefcsname@{dir^{`}}{\aturn@}
  4708. \xydefcsname@{dir_{`}}{\bturn@}
  4709.  
  4710. \xydef@\aturn@{\tip@x\aturn@@}
  4711. \xydef@\aturn@@{\setboxz@h{\xybsqlfont
  4712.   \vDirection@(1,-1){.707107\xybsqll@}\kern-\dX
  4713.   \lower\dY\hbox{\DirectionChar}}%
  4714.  \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4715.  
  4716. \xydef@\bturn@{\tip@x\bturn@@}
  4717. \xydef@\bturn@@{\setboxz@h{\xybsqlfont
  4718.   \vDirection@(-1,-1){.707107\xybsqll@}\DirectionChar}%
  4719.  \wdz@=\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4720. \DOCMODE)
  4721.  
  4722. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4723.  
  4724. \note??=[Constructed tips]
  4725.  
  4726.     These tips are combinations of the plain tips provided for
  4727.     convenience (and optimised for efficiency).  New ones can be
  4728.     constructed using |\composite| and by declarations of the form
  4729. %
  4730. \begin{defs1}
  4731. %
  4732.  |\newdir| <dir> |{|<composite>|}|\cr
  4733. %
  4734. \end{defs1}
  4735. \noindent\unskip
  4736. %
  4737.     which defines |\dir|<dir> as the <composite> (see note~??[composite
  4738.     object box] for the details).
  4739.  
  4740. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4741.  
  4742.     |\newdir| is simple:
  4743.  
  4744. \DOCMODE(
  4745. \xydef@\newdir#1#{\newdir@{#1}}
  4746.  
  4747. \xydef@\newdir@#1#2#3{\xydefcsname@{dir#1{#2}}{\composite@{}{#3}}}
  4748. \DOCMODE)
  4749.  
  4750.     Then the somewhat more efficient |\shiftdir@| used internally for
  4751.     moving a tip in the current direction---it does so by making a local
  4752.     hbox within which the argument tip is constructed and subsequently
  4753.     shifted and made of zero size.  Use as
  4754. $$
  4755.  |\shiftdir@|<tip@><dimen><tip@>
  4756. $$
  4757.     where <tip@> means a tip command without the leading |\hbox{|.
  4758.  
  4759. \DOCMODE(
  4760. \xydef@\shiftdir@#1#2{%
  4761.  \setbox\z@=\hbox\bgroup#1\relax
  4762.  \setboxz@h{\dimen@ii=#2\relax
  4763.   \dimen@=-\cosDirection\dimen@ii \advance\dimen@-\Lc
  4764.   \kern\dimen@ \lower\sinDirection\dimen@ii\boxz@}%
  4765.  \wdz@\z@ \ht\z@=\z@ \dp\z@=\z@ \boxz@}
  4766. \DOCMODE)
  4767.  
  4768.     Then the tips, with the |\tipjot@| hook allowing changing the spacing
  4769.     of tips used for single lines.
  4770.  
  4771. \DOCMODE(
  4772. \xylet@\tipjot@=\jot
  4773.  
  4774. \xydefcsname@{dir1{>>}}{\shiftdir@\tip@\tipjot@ \tip@}
  4775. \xydefcsname@{dir^{>>}}{\shiftdir@\atip@\tipjot@ \atip@}
  4776. \xydefcsname@{dir_{>>}}{\shiftdir@\btip@\tipjot@ \btip@}
  4777. \xydefcsname@{dir2{>>}}{\composite@{}{h!/\tipjot@/\dir2{>}*\dir2{>}}}
  4778. \xydefcsname@{dir3{>>}}{\composite@{}{h!/\tipjot@/\dir3{>}*\dir3{>}}}
  4779. \xyletcsnamecsname@{dir0{>>}}{dir{}}
  4780. \xyletcsnamecsname@{dir{>>}}{dir1{>>}}
  4781.  
  4782. \xydefcsname@{dir1{<<}}{\reverseDirection@ \shiftdir@\tip@\tipjot@ \tip@}
  4783. \xydefcsname@{dir^{<<}}{\reverseDirection@ \shiftdir@\btip@\tipjot@ \btip@}
  4784. \xydefcsname@{dir_{<<}}{\reverseDirection@ \shiftdir@\atip@\tipjot@ \atip@}
  4785. \xydefcsname@{dir2{<<}}{\composite@{}{h!/-\tipjot@/\dir2{<}*\dir2{<}}}
  4786. \xydefcsname@{dir3{<<}}{\composite@{}{h!/-\tipjot@/\dir3{<}*\dir3{<}}}
  4787. \xyletcsnamecsname@{dir0{<<}}{dir{}}
  4788. \xyletcsnamecsname@{dir{<<}}{dir1{<<}}
  4789.  
  4790. \xydefcsname@{dir{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
  4791.  \pointlike@{}\jot}
  4792. \xydefcsname@{dir^{||}}{\shiftdir@{\aboveDirection@\xydashl@\line@}\xydashh@
  4793.  \shiftdir@{\aboveDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
  4794. \xydefcsname@{dir_{||}}{\shiftdir@{\belowDirection@\xydashl@\line@}\xydashh@
  4795.  \shiftdir@{\belowDirection@\xydashl@\line@}\z@ \pointlike@{}\jot}
  4796. \xydefcsname@{dir2{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
  4797.  \pointlike@{}\jot \double@\xydashh@}
  4798. \xydefcsname@{dir3{||}}{\shiftdir@\stopper@\xydashh@ \shiftdir@\stopper@\z@
  4799.  \pointlike@{}\jot \double@{2\xydashh@}}
  4800.  
  4801. \xydefcsname@{dir{>|}}{\shiftdir@\stopper@\z@ \tip@}
  4802.  
  4803. \xydefcsname@{dir{>>|}}{\shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
  4804.  
  4805. \xydefcsname@{dir{|<}}{\reverseDirection@ \shiftdir@\stopper@\z@ \tip@}
  4806.  
  4807. \xydefcsname@{dir{|<<}}{\reverseDirection@
  4808.  \shiftdir@\stopper@\z@ \shiftdir@\tip@\tipjot@ \tip@}
  4809.  
  4810. \xydefcsname@{dir{|-}}{\shiftdir@\stopper@\z@
  4811.  \shiftdir@\line@\z@ \pointlike@{}\jot}
  4812. \xydefcsname@{dir^{|-}}{\shiftdir@{\aboveDirection@\xydashl@ \line@}\z@
  4813.  \shiftdir@\line@\z@ \pointlike@{}\jot}
  4814. \xydefcsname@{dir_{|-}}{\shiftdir@{\belowDirection@\xydashl@ \line@}\z@
  4815.  \shiftdir@\line@\z@ \pointlike@{}\jot}
  4816. \xydefcsname@{dir2{|-}}{\shiftdir@\stopper@\z@
  4817.  \shiftdir@\line@\z@ \pointlike@{}\jot \double@\xydashh@}
  4818. \xydefcsname@{dir3{|-}}{\shiftdir@\stopper@\z@
  4819.  \shiftdir@\line@\z@ \pointlike@{}\jot \triple@\xydashh@}
  4820.  
  4821. %\xydefcsname@{dir^{|-}}{\composite@{}{\dir^{|}*\dir{-}}}
  4822. %\xydefcsname@{dir_{|-}}{\shiftdir@{\belowDirection@\xydashl@\line@}\z@\line@}
  4823. %\xydefcsname@{dir2{|-}}{\shiftdir@\stopper@\z@ \line@ \double@\xydashh@}
  4824. %\xydefcsname@{dir3{|-}}{\shiftdir@\stopper@\z@ \line@ \triple@\xydashh@}
  4825.  
  4826. \xyletcsnamecsname@{dir0{|=}}{dir{}}
  4827. \xyletcsnamecsname@{dir{|=}}{dir2{|-}}
  4828.  
  4829. \xydefcsname@{dir{+}}{%
  4830.  \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
  4831. \xydefcsname@{dir{x}}{\vDirection@(1,1)\jot
  4832.  \DN@##1{\composite@{}{##10\dir{|}*!C##10\dir{-}}}\addEQ@\next@}
  4833. \xydefcsname@{dir{/}}{\vDirection@(1,-.3)\jot \stopper@}
  4834.  
  4835. \xydefcsname@{dir{*}}{\solidpoint@}
  4836. \xydef@\solidpoint@{%
  4837.  \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\bullet$}}\jot}
  4838.  
  4839. \xydefcsname@{dir{o}}{\hollowpoint@}
  4840. \xydef@\hollowpoint@{%
  4841.  \pointlike@{\kern-1.8pt\lower1.8pt\hbox{$\scriptstyle\circ$}}\jot}
  4842. \DOCMODE)
  4843.  
  4844. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4845.  
  4846. \end{notes}
  4847.  
  4848. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4849.  
  4850.  
  4851. \subsection{Circle segments}
  4852. ??=[objectlib.circles]
  4853.  
  4854. \DOCMODE(
  4855. \message{circles,}
  4856. \DOCMODE)
  4857.  
  4858.     Circle <object>s are round and typeset a segment of the circle
  4859.     centered at the reference point.  The syntax of circles is described
  4860.     in figure~??[f.cir] with explanations below.
  4861.  
  4862. \begin{figure*}
  4863. \vss
  4864. \begin{syntax}
  4865. %
  4866.  \multispan3|\cir| <radius> |{| <cir> |}|\hfil
  4867.     & <cir>cle segment with <radius>
  4868. \cr
  4869. \noalign{\nobreak\smallskip\nobreak\hrule\nobreak\smallskip\nobreak}
  4870. %
  4871.  ??w![<radius>]
  4872.   &\iss    & <empty>
  4873.     & use $R_c$ as the radius
  4874. \cr
  4875.   &\orr    & <vector>
  4876.     & use $X$ of the <vector> as radius
  4877. \cr
  4878. \noalign{\smallbreak}
  4879. %
  4880.  ??w![<cir>]
  4881.   &\iss    & <empty>
  4882.     & full circle of <radius>
  4883. \cr
  4884.   &\orr    & <diag> <orient> <diag>
  4885.     & partial circle from first <diag>onal through to the
  4886.       second <diag>onal in the <orient>ation
  4887. \cr
  4888. \noalign{\smallbreak}
  4889. %
  4890.  ??w![<orient>]
  4891.   &\iss    & |^|
  4892.     & anticlockwise
  4893. \cr
  4894.   &\orr    & |_|
  4895.     & clockwise
  4896. \cr
  4897. \end{syntax}
  4898. \caption{\protect<cir>cles.}
  4899. ??=[f.cir]
  4900. \vfill
  4901. \end{figure*}
  4902.  
  4903. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4904.  
  4905.     The |\cir| command is the hub: it parses the optional <radius> (to
  4906.     |\R@|, default from $R_c$) and |{|<cir>|}|, bailing out with a
  4907.     |\zerodot| if the radius is to small:
  4908.  
  4909. \DOCMODE(
  4910. \xydef@\cir#1#{\hbox\bgroup
  4911.  \afterVECTORorEMPTY{\xy@@{\R@=\Xc}\cir@}{\xy@@{\R@=\Rc}\cir@}#1@}
  4912.  
  4913. \xydef@\cir@#1@#2{%
  4914.  \DN@{#1}\ifx\next@\empty\else \xyerror@{illegal circle <radius>: must be
  4915.     <vector> or <empty>}{}\fi
  4916.  \afterCIRorDIAG{\xyFN@\cir@cir}{\xyFN@\cir@diag}#2@}
  4917. \DOCMODE)
  4918.  
  4919.     The code to actually typeset the <cir> just parsed starts by checking
  4920.     that the <cir> was immediately followed by the |@| we put there in
  4921.     |\cir|:
  4922.  
  4923. \DOCMODE(
  4924. \xydef@\cir@cir{%
  4925.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\cir@cir}%gobble spaces
  4926.  \else \ifx @\next \DN@ @{\cir@i}%
  4927.  \else \xyerror@{illegal <cir>: must have form <diag><orient><diag> or
  4928.     <empty>}{}%
  4929.  \fi\fi \next@}
  4930. \DOCMODE)
  4931.  
  4932.     Similarly when an <empty> one was given---the parser will recognise
  4933.     this as a <diag> but we hack that here:
  4934.  
  4935. \DOCMODE(
  4936. \xydef@\cir@diag{%
  4937.  \DN@{\xyerror@{illegal <cir>: must have form <diag><orient><diag> or
  4938.     <empty>}{}}%
  4939.  \ifx @\next \ifnum\count@=8 %
  4940.    \DN@ @{\def\CIRin@@{0}\def\CIRorient@@{\CIRfull@}\def\CIRout@@{7}\cir@i}%
  4941.  \fi\fi \next@}
  4942. \DOCMODE)
  4943.  
  4944.     \dots and then use the constructed methods to build it:
  4945.  
  4946. \DOCMODE(
  4947. \xydef@\cir@i{%
  4948.  \ifnum\CIRin@@=8 \xyerror@{incomplete <cir> specification}{%
  4949. The <cir> you specified as <diag><orient><diag> is not sufficiently specific.}%
  4950.   \def\CIRin@@{0}\fi
  4951.  \ifdim\R@<.5\p@ \R@=\z@ \zerodot
  4952.  \else \CIRorient@@ \cirbuild@ \fi
  4953.  \Lc=\R@ \Rc=\R@ \Dc=\R@ \Uc=\R@ \def\Leftness@{.5}\def\Upness@{.5}%
  4954.  \def\Drop@@{\boxz@}\def\Connect@@{\straight@\relax}\Edgec={\circleEdge}%
  4955.  \OBJECT@x}
  4956. \DOCMODE)
  4957.  
  4958. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4959.  
  4960. \paragraph*{Parsing:}
  4961.  
  4962.     The |\afterCIRorDIAG| parser handles the parsing: it either
  4963. %
  4964. \begin{itemize}
  4965. \item
  4966.     parses the <cir> and sets "in", "orient", and "out", and passes
  4967.     control to the first argument continuation, or
  4968. \item
  4969.     parses the single <diag> specified, store it in |\count@| (as |8| if
  4970.     an <empty> one given), and pass control to the second continuation
  4971.     argument,
  4972. \end{itemize}
  4973. %
  4974.     where the <diag> internal representation number of note~??[diagonal]
  4975.     of is used.  An <empty> circle is treated as an <empty> diagonal;
  4976.     specifying an <empty> first <diag> of a <cir> is equivalent to using
  4977.     the value of the "in" method at call time.
  4978.  
  4979.     The parser is very simple, setting methods stored in the usual
  4980.     |@@|-terminated control sequences (\TODO: Rename all non-method
  4981.     control sequences that end in |@@|\dots to use |@|<romannumeral>
  4982.     suffixes\dots):
  4983.  
  4984. \DOCMODE(
  4985. \xydef@\CIRin@@{3}
  4986. \xydef@\CIRout@@{3}
  4987. \xylet@\CIRorient@@=\empty
  4988.  
  4989. \xydef@\afterCIRorDIAG#1#2{\def\afterCIR@{#1}\def\afterCIRDIAG@{#2}\xyFN@\CIR@}
  4990.  
  4991. \xylet@\afterCIR@=\empty
  4992. \xylet@\afterCIRDIAG@=\empty
  4993.  
  4994. \xydef@\CIR@{\count@=8 \afterDIAG{\edef\CIRin@@{\the\count@}\xyFN@\CIR@@}}
  4995.  
  4996. \xydef@\CIR@@{%
  4997.  \ifx \space@\next \expandafter\DN@\space{\xyFN@\CIR@@}%gobble spaces
  4998.  \else\ifx ^\next
  4999.   \DN@ ^{\def\CIRorient@@{\CIRacw@}%
  5000.    \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
  5001.  \else\ifx _\next
  5002.   \DN@_{\def\CIRorient@@{\CIRcw@}%
  5003.    \afterDIAG{\edef\CIRout@@{\the\count@}\afterCIR@}}%
  5004.  \else
  5005.   \DN@{\def\CIRorient@@{\relax}\afterCIRDIAG@}%
  5006.  \fi\fi\fi \next@}
  5007. \DOCMODE)
  5008.  
  5009. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5010.  
  5011.     The default is to generate a "full circle" with the specified radius,
  5012.     \eg,
  5013. $$
  5014. \def\quotesmash#1{\setbox0=\hbox{``$\vcenter{#1}$''}\ht0=8pt \dp0=3pt \box0}
  5015. \begin{array}{ccc}
  5016.  |\xy*\cir<4pt>{}\endxy|
  5017.     &\hbox{typesets}& \quotesmash{\xy*\cir<4pt>{}\endxy}
  5018. \cr
  5019.  |\xy*{M}*\cir{}\endxy|
  5020.     &\hbox{---}& \quotesmash{\xy*{M}*\cir{}\endxy}
  5021. \end{array}
  5022. $$
  5023.     All the other circle segments are subsets of this and have the shape
  5024.     that the full circle outlines.
  5025.  
  5026. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5027.  
  5028.     Finally we present the "orient" methods.  They use these `internal
  5029.     methods' to actually draw the circles
  5030.  
  5031. \DOCMODE(
  5032. \xylet@\CIRtest@@=\relax
  5033. \xydef@\CIRlo@@{0}
  5034. \xydef@\CIRhi@@{0}
  5035. \DOCMODE)
  5036.  
  5037.     Below we call them "lo", "hi", and "test"; the first two are coded as
  5038.     described in note ??[diagonal] and the last takes two arguments: a
  5039.     dimension and something to do if the test succeeds.  |\count@@| and
  5040.     |\count@| should be set to "in" and "out" internally as well in case
  5041.     |\cirbuild@| and friends below should be used.
  5042.  
  5043.     The dummy "orient" used for simple circles is the simplest:
  5044.  
  5045. \DOCMODE(
  5046. \xydef@\CIRfull@{\def\CIRtest@@##1##2{##2}}
  5047. \DOCMODE)
  5048.  
  5049.     The kernel |\cirbuild@| builds the actual <object> using characters
  5050.     from the |\xycircfont| assumed coded like |xycirc10.mf|:
  5051.     |\cirrestrict@@| choses a group and adjusts the radius |\R@| to fit it
  5052.     exactly.  The group is multiplied by 8 to get the group character
  5053.     offset [|\count@|].
  5054.  
  5055. \DOCMODE(
  5056. \xydef@\cirbuild@{\cirrestrict@@ \multiply\count@8 %
  5057.  \circhar@0\circhar@7\kern\dimen@
  5058.  \circhar@1\circhar@6\kern\dimen@
  5059.  \circhar@2\circhar@5\kern\dimen@
  5060.  \circhar@3\circhar@4\kern\dimen@}
  5061.  
  5062. \xydef@\circhar@#1{%
  5063.  \setboxz@h{\circhar@@{#1}}\dimen@=\wdz@ \wdz@=\z@ \ht\z@=\R@ \dp\z@=\R@
  5064.  \CIRtest@@#1{\boxz@}\setbox\z@=\copy\voidb@x}
  5065.  
  5066. \xydef@\circhar@@#1{{\xycircfont \advance\count@#1\relax \char\count@}}
  5067. \DOCMODE)
  5068.  
  5069.     |\cirrestrict@@| computes the group $g$ [|\count@|] of circle segments
  5070.     to use from the radius $r$ [|\R@|] using the formula (the reverse of
  5071.     the one in |xycirc10.mf|)
  5072. $$
  5073. \def\arraystretch{1}
  5074. g = \left\{ \begin{array}{ll}
  5075.  \floor{r\over1|pt|}-1    &\text{if}~ 1|pt|\le r\lt  8|pt|\\
  5076.  \floor{r\over2|pt|}+3    &\text{if}~ 8|pt|\le r\lt 16|pt|\\
  5077.  \floor{r\over4|pt|}+7    &\text{if}~16|pt|\le r\lt 32|pt|\\
  5078.  15            &\text{if}~32|pt|\le r        \end{array}
  5079. \right.
  5080. $$
  5081.     (where we know from |\cir@i| that $r\ge\frac12|pt|$), and then
  5082.     adjusts the radius to be exactly the one chosen through the use of
  5083.     group $g$ using the formula in |xycirc10.mf|\dots this is necessary
  5084.     because of the restriction on |tfm| files that they can only have 15
  5085.     different nonzero heights and depths.  Subsequent calls to
  5086.     |\cirrestrict@@| should compute the same values.
  5087.  
  5088. \DOCMODE(
  5089. \xydef@\cirrestrict@@{\dimen@=\R@
  5090.  \ifdim\R@<8pt \count@=\dimen@ \divide\count@\p@ \advance\count@\m@ne
  5091.  \else\ifdim\R@<16pt \count@=\dimen@
  5092.   \dimen@=2\p@ \divide\count@\dimen@ \advance\count@3 %
  5093.  \else\ifdim\R@<32pt \count@=\dimen@
  5094.   \dimen@=4\p@ \divide\count@\dimen@ \advance\count@7 %
  5095.  \else \count@=15 \fi\fi\fi
  5096.  \R@=\p@
  5097.  \ifnum\count@<8 \multiply\R@\count@ \advance\R@\p@
  5098.  \else\ifnum\count@<12 \multiply\R@\count@ \multiply\R@\tw@ \advance\R@-6\p@
  5099.  \else\ifnum\count@<16 \multiply\R@\count@ \multiply\R@ 4 \advance\R@-28\p@
  5100.  \else \multiply\R@ 32 \fi\fi\fi}
  5101. \DOCMODE)
  5102.  
  5103. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5104.  
  5105.     "Partial circle segments" with <orient>ation are the part of the full
  5106.     circle that starts with a tangent vector in the direction of the
  5107.     first <diag>onal (see note~??[diagonal]) and ends with a tangent
  5108.     vector in the direction of the other <diag>onal after a clockwise
  5109.     (for |_|) or anticlockwise (for |^|) turn, \eg,
  5110. $$
  5111. \def\quotesmash#1{\setbox0=\hbox{``$\vcenter{#1}$''}\ht0=8pt \dp0=3pt \box0}
  5112. \begin{array}{ccc}
  5113.  |\xy*\cir<4pt>{l^r}\endxy|
  5114.     &\hbox{typesets}& \quotesmash{\xy*\cir<4pt>{l^r}\endxy}
  5115. \\
  5116.  |\xy*\cir<4pt>{l_r}\endxy|
  5117.     &\hbox{---}& \quotesmash{\xy*\cir<4pt>{l_r}\endxy}
  5118. \\
  5119.  |\xy*\cir<4pt>{dl^u}\endxy|
  5120.     &\hbox{---}& \quotesmash{\xy*\cir<4pt>{dl^u}\endxy}
  5121. \\
  5122.  |\xy*\cir<4pt>{dl_u}\endxy|
  5123.     &\hbox{---}& \quotesmash{\xy*\cir<4pt>{dl_u}\endxy}
  5124. \\
  5125.  |\xy*+{M}*\cir{dr_ur}\endxy|
  5126.     &\hbox{---}& \quotesmash{\xy*+{M}*\cir{dr_ur}\endxy}
  5127. \end{array}
  5128. $$
  5129.     If the same <diag> is given twice then nothing is typeset, \eg,
  5130. $$
  5131. \def\quotesmash#1{\setbox0=\hbox{``$\vcenter{#1}$''}\ht0=8pt \dp0=3pt \box0}
  5132. \begin{array}{ccc}
  5133.  |\xy*\cir<4pt>{u^u}\endxy|
  5134.     &\hbox{typesets}& \quotesmash{\xy*\cir<4pt>{u^u}\endxy}
  5135. \end{array}
  5136. $$
  5137.     Special care is taken to setup the <diag>onal defaults:
  5138. %
  5139. \begin{itemize}
  5140. \item
  5141.     After |^| the default is the diagonal $90^\circ$ anticlockwise from
  5142.     the one before the |^|.
  5143. \item
  5144.     After |_| the default is the diagonal $90^\circ$ clockwise from the
  5145.     one before the |_|.
  5146. \end{itemize}
  5147. %
  5148.     The <diag> before |^| or |_| is required for |\cir| <objects>.
  5149.  
  5150. \begin{exercise}
  5151.     Typeset the following shaded circle with radius |5pt|:
  5152. %
  5153. \begin{code}
  5154. $$\xy
  5155.  *\cir<5pt>{}
  5156.  *!<-.2pt,.2pt>\cir<5pt>{dr^ul}
  5157.  *!<-.4pt,.4pt>\cir<5pt>{dr^ul}
  5158.  *!<-.6pt,.6pt>\cir<5pt>{dr^ul}
  5159. \endxy$$
  5160. \end{code}
  5161. \docode
  5162. %
  5163. \answertext{One way is to add extra half circles skewed such that they create
  5164.     the illusion of a shade:}
  5165. \answercode
  5166. \answertext\displaycode
  5167. \end{exercise}
  5168.  
  5169. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5170.  
  5171.     These two macros implement the defaults and setup of "lo" and "hi"
  5172.     for anticlockwise and clockwise segments.  Here is what they set:
  5173. $$
  5174. \begin{array}{\otherbar c\otherbar cc\otherbar l\otherbar}
  5175. \hline
  5176.  ??w![<cir>] & "lo" & "hi" & "test"(s) \\
  5177. \hline
  5178.  d_1|^|d_2, d_1\le d_2 & d_1 -_8 1 & d_2 -_8 1 & {"lo"\le s}\wedge{s\lt "hi"}\\
  5179.  d_1|^|d_2, d_1\gt d_2 & d_2 -_8 1 & d_1 -_8 1 & {s \lt"lo"} \vee {"hi"\le s}\\
  5180.  d_1|_|d_2, d_1\lt d_2 & d_1 +_8 3 & d_2 +_8 3 & {s \lt"lo"} \vee {"hi"\le s}\\
  5181.  d_1|_|d_2, d_1\ge d_2 & d_2 +_8 3 & d_1 +_8 3 & {"lo"\le s}\wedge{s\lt "hi"}\\
  5182. \hline
  5183. \end{array}
  5184. $$
  5185.     where $+_8$ and $-_8$ are $+$ and $-$ modulo 8; $d_1$ and $d_2$ are
  5186.     in |\count@@| and |\count@|, respectively.
  5187.  
  5188. \DOCMODE(
  5189. \xydef@\CIRacw@{\count@@=\CIRin@@ \count@=\CIRout@@
  5190.  \ifnum\count@=8 \count@=\count@@
  5191.   \ifnum\count@<6 \advance\count@\tw@ \else \advance\count@-6 \fi \fi
  5192.  \ifnum\count@@<\@ne \advance\count@@7 \else \advance\count@@\m@ne \fi
  5193.  \ifnum\count@<\@ne \advance\count@7 \else \advance\count@\m@ne \fi
  5194.  \ifnum\count@@>\count@ \let\CIRtest@@=\CIRtest@outside
  5195.   \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
  5196.  \else \let\CIRtest@@=\CIRtest@inside
  5197.   \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
  5198.  \fi}
  5199.  
  5200. \xydef@\CIRcw@{\count@@=\CIRin@@ \count@=\CIRout@@
  5201.  \ifnum\count@=8 \count@=\count@@
  5202.   \ifnum\count@>\@ne \advance\count@-\tw@ \else \advance\count@6 \fi \fi
  5203.  \ifnum\count@@<5 \advance\count@@\thr@@ \else \advance\count@@-5 \fi
  5204.  \ifnum\count@<5 \advance\count@\thr@@ \else \advance\count@-5 \fi
  5205.  \ifnum\count@@<\count@ \let\CIRtest@@=\CIRtest@outside
  5206.   \edef\CIRlo@@{\the\count@@}\edef\CIRhi@@{\the\count@}%
  5207.  \else \let\CIRtest@@=\CIRtest@inside
  5208.   \edef\CIRlo@@{\the\count@}\edef\CIRhi@@{\the\count@@}%
  5209.  \fi}
  5210.  
  5211. \xydef@\CIRtest@inside#1#2{\let\next@=\relax
  5212.  \ifnum\CIRlo@@>#1\else \ifnum#1<\CIRhi@@\DN@{#2}\fi\fi \next@}
  5213.  
  5214. \xydef@\CIRtest@outside#1#2{\let\next@=\relax
  5215.  \ifnum\CIRlo@@>#1\DN@{#2}\else \ifnum#1<\CIRhi@@\else\DN@{#2}\fi\fi \next@}
  5216. \DOCMODE)
  5217.  
  5218. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5219.  
  5220.  
  5221. \subsection{Text}
  5222. ??=[objectlib.text]
  5223.  
  5224. \DOCMODE(
  5225. \message{text;}
  5226. \DOCMODE)
  5227.  
  5228.     Text in pictures is supported through the <object> construction
  5229. %
  5230. \begin{defs1}
  5231. |\txt| <width> <style> |{|<text>|}|\cr
  5232. \end{defs1}
  5233. \noindent\unskip
  5234. %
  5235.     that builds an object containing <text> typeset to <width> using
  5236.     <style>; in <text> |\\| can be used as an explicit line break; all
  5237.     lines will be centered.  <style> should either be a font command or
  5238.     some other stuff to do for each line of the <text> and <width> should
  5239.     be either |<|<dimen>|>| or <empty>.
  5240.  
  5241. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5242.  
  5243.     The code just parses the <size> defaulting it to |<\maxdimen,0pt>|
  5244.     which is recognised as `free form'.
  5245.  
  5246. \DOCMODE(
  5247. \xydef@\txt{\hbox\bgroup \xyFN@\txt@}
  5248.  
  5249. \xydef@\txt@{%
  5250.  \addLT@\ifx\next \addGT@{\addLT@\DN@##1}{\A@=##1\txt@i}%
  5251.  \else \DN@{\A@=\maxdimen \txt@i}\fi \next@}
  5252.  
  5253. \xydef@\txt@i#1#{%
  5254.  \setboxz@h{#1\mathstrut}\dimen@=\ht\z@ \advance\dimen@\dp\z@
  5255.  \baselineskip=1.1\dimen@ \lineskip=.2\dimen@ \lineskiplimit=\lineskip
  5256.  \def\txtline@@##1{\txtline@{#1}{##1}}\object@\txt@ii}
  5257.  
  5258. \xylet@\txtline@@=\eat@
  5259. \xydef@\txtline@#1#2{\relax\setboxz@h{#1\ignorespaces #2\unskip}%
  5260.  \ifdim\A@<\wdz@ \setboxz@h{\hsize=\A@
  5261.    \leftskip=0pt plus4em \rightskip=\leftskip
  5262.    \parfillskip=0pt \parindent=0pt %
  5263.    \spaceskip=.3333em \xspaceskip=.5em %
  5264.    \pretolerance=9999 \tolerance=9999 %
  5265.    \hyphenpenalty=9999 \exhyphenpenalty=9999 %
  5266.    \vbox{#1\noindent\ignorespaces #2\unskip}}%
  5267.  \else\ifdim\A@<\maxdimen\setboxz@h to\A@{\hfil\boxz@\hfil}\fi\fi
  5268.  \boxz@}
  5269.  
  5270. \xydef@\txt@ii#1{\vbox{%
  5271.   \let\\=\cr
  5272.   \tabskip=\z@skip \halign{\relax\hfil\txtline@@{##}\hfil\cr#1\crcr}}}
  5273. \DOCMODE)
  5274.  
  5275. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5276.  
  5277.  
  5278.  
  5279. \section{\XY-pic option interface}
  5280. ??=[option]
  5281. %
  5282.     \NOTE: \LaTeX\ users should also consult the paragraph on ``xy.sty''
  5283.     in~\S??[env.loading].
  5284.  
  5285.     \XY-pic is provided with a growing number of options supporting
  5286.     specialised drawing tasks as well as exotic output devices with
  5287.     special graphic features.  These should all be loaded using this
  5288.     uniform interface in order to ensure that the \XY-pic environment is
  5289.     properly set up while reading the option.
  5290. %
  5291. \begin{defs1}
  5292. %
  5293.   |\xyoption| |{| <option> |}| \cr
  5294.   |\xyrequire| |{| <option> |}|
  5295. %
  5296. \end{defs1}
  5297. \noindent\unskip
  5298. %
  5299.     |\xyoption| will load the \XY-pic option file |xy|<option>|.tex|;
  5300.     |\xyrequire| will do so only if it is not already loaded, if it is
  5301.     then nothing happens.
  5302.  
  5303. \DOCMODE(
  5304. \message{options;}
  5305.  
  5306. \xylet@\xyoption@@=\relax
  5307.  
  5308. \xydef@\xyoption#1{\xyinputorelse@{xy#1}%
  5309.   {\DN@{#1}\edef\next@{\codeof\next@}\xyerror@{No `\next@' option}{%
  5310. Your \string\xyoption\string{\next@\string} request could not be granted: the
  5311. required^^J%
  5312. file `xy\next@.tex' could not be located. Please make sure that it is^^J%
  5313. properly installed before continuing.}}%
  5314.  \def\xyoption@@{#1}\edef\xyoption@@{\codeof\xyoption@@}\xywith@@
  5315.  \ignorespaces}
  5316.  
  5317. \xydef@\xyrequire#1{\DN@{#1}%
  5318.  \expandafter\let\expandafter\next@\csname xy\codeof\next@ loaded\endcsname
  5319.  \ifx \next@\relax \DN@{\xyoption{#1}}\else \DN@{}\fi \next@}
  5320. \DOCMODE)
  5321.  
  5322.     Sometimes some declarations of an option or header file or whatever
  5323.     only makes sense after some particular other option is loaded.  In
  5324.     that case the code should be wrapped in the special command
  5325. %
  5326. \begin{defs1}
  5327. %
  5328.   |\xywithoption| |{| <option> |}| |{| <code> |}| \cr
  5329. %
  5330. \end{defs1}
  5331. \noindent\unskip
  5332. %
  5333.     which indicates that if the <option> is already loaded then <code>
  5334.     should be executed now, otherwise it should be saved and if <option>
  5335.     ever gets loaded then <code> should be executed afterwords.
  5336.  
  5337. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5338.  
  5339.     \NOTE: The <code> is saved with the catcodes at the time of the
  5340.     |\xywithoption| command.
  5341.  
  5342. \DOCMODE(
  5343. \xylet@\xywith@@=\empty
  5344.  
  5345. \xydef@\xywithoption#1#2{\DN@{#1}%
  5346.  \expandafter\let\expandafter\next@\csname xy\codeof\next@ loaded\endcsname
  5347.  \ifx \next@\relax
  5348.   \expandafter\def\expandafter\xywith@@\expandafter{\xywith@@
  5349.    \DN@{#1}\edef\next@{\codeof\next@}%
  5350.    \ifx\next@\xyoption@@ \DN@{#2}%
  5351.    \else \let\next@=\relax \fi \next@}%
  5352.  \else \DN@{#2}\fi \next@}
  5353. \DOCMODE)
  5354.  
  5355. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5356.  
  5357.     Finally a description of the format of option files: they must look
  5358.     like
  5359.  
  5360. \begin{quote}
  5361.  |%%| <identification> \\
  5362.  |%%| <copyright, \dots>
  5363.  
  5364.  |\ifx\xyloaded\undefined \input xy \fi|
  5365.  
  5366.  |\xyprovide{|<option>|}{|<name>|}{|<version>|}%| \\
  5367.  \null\qquad\qquad |{|<author>|}{|<email>|}{|<address>|}|
  5368.  
  5369.  ??w![<body of the option>]
  5370.  
  5371.  |\xyendinput|
  5372. \end{quote}
  5373. %
  5374.     The 6 arguments to |\xyprovide| should contain the following:
  5375. %
  5376. \begin{description}
  5377. \item[<option>]
  5378.     Option load name as used in the |\xyoption| command.  This should be
  5379.     safe and distinguishable for any operating system and is thus limited
  5380.     to 6 characters chosen among the lowercase letters (|a|--|z|), digits
  5381.     (|0|--|9|), and dash (|-|).
  5382. \item[<name>]
  5383.     Descriptive name for the option.
  5384. \item[<version>]
  5385.     Identification of the version of the option.
  5386. \item[<author>]
  5387.     The name(s) of the author(s).
  5388. \item[<email>]
  5389.     The electronic mail address(es) of the author(s) "or" the affiliation
  5390.     if no email is available.
  5391. \item[<address>]
  5392.     The postal address(es) of the author(s).
  5393. \end{description}
  5394. %
  5395.     This information is used not only to print a nice banner but also to
  5396.     (1)~silently skip loading if the same version was preloaded and
  5397.     (2)~print an error message if a different version was preloaded.
  5398.  
  5399. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5400.  
  5401.     The |\xyprovide| command checks that the option is not already loaded
  5402.     and that the loaded version is the same as the preloaded one by
  5403.     checking the existence and contents of the macro
  5404.     |\xy|<option>|loaded|.  Finally it calls |\xycatcodes| such that the
  5405.     option internals are loaded in `\TeX\ programming mode'.
  5406.     |\xyendinput| undoes this.
  5407.  
  5408. \DOCMODE(
  5409. \xydef@\xyprovide#1#2#3#4#5#6{%
  5410.  \def\next{#1}\edef\next{\codeof\next}\edef\next@{#3}%
  5411.  \message{XY-pic option: #2 v.\next@}%
  5412.  \expandafter\let\expandafter\nextii@\csname xy\next loaded\endcsname
  5413.  \ifx \next@\nextii@ \message{not reloaded}\endinput
  5414.  \else
  5415.   \ifx \nextii@\relax\else \xyerror@{Option `\next' version mismatch}{%
  5416. You previously loaded, or the format has preloaded, a different version^^J%
  5417. of this option.  Just hit return to try to load this version instead (and^^J%
  5418. be prepared for a lot of warnings about redefinitions).}%
  5419.   \fi
  5420.   \expandafter\let\csname xy\next loaded\endcsname=\next@
  5421.   \expandafter\let\expandafter\xyenddocmode@\csname DOCMODE\endcsname
  5422.   \expandafter\let\csname DOCMODE\endcsname\xyprovidedocmode@
  5423.   \xycatcodes
  5424.  \fi \ignorespaces}
  5425.  
  5426. \xydef@\xyendinput{\expandafter\let\csname DOCMODE\endcsname=\xyenddocmode@
  5427.  \message{loaded}\xyuncatcodes\endinput}
  5428. \DOCMODE)
  5429.  
  5430.     It is futher complicated by the |DOCMODE| format (see below).
  5431.  
  5432. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5433.  
  5434. \paragraph*{DOCMODE format:}
  5435.  
  5436.     Some trickery is involved because options may use the |DOCMODE|
  5437.     format without any restrictions.  So we make sure that the dummy one
  5438.     defined in the |xy.tex| file header is active now since we are
  5439.     executing code.
  5440.  
  5441. \DOCMODE(
  5442. \expandafter\xylet@\expandafter\xyprovidedocmode@\csname DOCMODE\endcsname
  5443. \xylet@\xyenddocmode@=\relax
  5444. \DOCMODE)
  5445.  
  5446.     Options should be written in the special |DOCMODE| format in order to
  5447.     be included in the distribution proper.  The `dummy' option described
  5448.     in~\S??g[:dummy] shows a minimal such option.
  5449.  
  5450. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5451.  
  5452.  
  5453.  
  5454. \section{Algorithms}
  5455. ??=[algo]
  5456.  
  5457.     This section presents the more complicated algorithms used in
  5458.     \XY-pic.
  5459.  
  5460. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5461.  
  5462.  
  5463. \subsection{Directions}
  5464. ??=[algo.direction]
  5465.  
  5466. \DOCMODE(
  5467. \message{algorithms: directions,}
  5468. \DOCMODE)
  5469.  
  5470.     The "direction state" is described by the following parameters:
  5471. %
  5472. \begin{defs}
  5473. "Direction" & `angle' of the direction on $]-4K\dots4K]$ unit square \cr
  5474. "dX","dY" & the vector $c-p$ \cr
  5475. "sdX","sdY" & sign of "dX" and "dY" \cr
  5476. |\K@dXdY|,|\K@dYdX| & quotients $K\frac{"dX"}{"dY"}$ and
  5477.     $K\frac{"dY"}{"dX"}$ (as dimensions in sp) \cr
  5478. "DirectionChar","SemiDirectionChar" & |\chardefs| for directional
  5479.     and semidirectional fonts \cr
  5480. "cosDirection","sinDirection" & factors in the range $]-1\dots1]$
  5481.     corresponding to cos and sin of Direction \cr
  5482. \end{defs}
  5483. %
  5484.     where the ``$]-4K\dots4K]$ unit square'' has the following angles:
  5485. $$
  5486. \xy *[]=<3pc>{}="c"*\frm{-},
  5487.   "c"; (-1,-1)**{},p+/4pc/ *+{0}    **\dir{-}?>*\dir{>},
  5488.   "c"; ( 0,-1)**{},p+/4pc/ *+{K}    **\dir{-}?>*\dir{>},
  5489.   "c"; ( 1,-1)**{},p+/4pc/ *+{2K}    **\dir{-}?>*\dir{>},
  5490.   "c"; ( 1, 0)**{},p+/4pc/ *+{3K}    **\dir{-}?>*\dir{>},
  5491.   "c"; ( 1, 1)**{},p+/4pc/ *+{4K}    **\dir{-}?>*\dir{>},
  5492.   "c"; ( 0, 1)**{},p+/4pc/ *+{{-}3K}    **\dir{-}?>*\dir{>},
  5493.   "c"; (-1, 1)**{},p+/4pc/ *+{{-}2K}    **\dir{-}?>*\dir{>},
  5494.   "c"; (-1, 0)**{},p+/4pc/ *+{{-}K}    **\dir{-}?>*\dir{>},
  5495. \endxy
  5496. $$
  5497.     where the intermediate $K$ angle in each interval correspond to
  5498.     equidistant points on the unit square.  Thus only for
  5499.     $n\in\{-3,2,1,0,1,2,3,4\}$ the angle of direction $n*K$ is exactly
  5500.     $n*45^\circ - 135^\circ$ ($0^\circ$ being the direction straight
  5501.     right).
  5502.  
  5503.     As usual |\DirectionfromtheDirection@| expands to code setting the
  5504.     current direction.
  5505.  
  5506. \DOCMODE(
  5507. \xydef@\DirectionfromtheDirection@{\noexpand\Direction=\the\Direction
  5508.  \noexpand\dX=\the\dX \noexpand\dY=\the\dY
  5509.  \def\noexpand\sdX{\sdX}\def\noexpand\sdY{\sdY}%
  5510.  \noexpand\K@dXdY=\the\K@dXdY \noexpand\K@dYdX=\the\K@dYdX
  5511.  \chardef\noexpand\DirectionChar=\the\DirectionChar
  5512.  \chardef\noexpand\SemiDirectionChar=\the\SemiDirectionChar
  5513.  \def\noexpand\cosDirection{\cosDirection}%
  5514.  \def\noexpand\sinDirection{\sinDirection}%
  5515.  \noexpand\resetupDirection@}
  5516. \DOCMODE)
  5517.  
  5518.     The actual direction computation is done using
  5519.     |\setupDirection@|.
  5520.  
  5521. \paragraph*{Procedure:}
  5522. %
  5523.     Is really not so complicated.  [??_[Dir1]]~"dX" and "dY" are computed
  5524.     from $c-p$ and we skip if the current setting is based on these (this
  5525.     is stored in the internal |\Directiontest@@| method);
  5526.     [??_[Diri1]]~if the direction is one of the principal ones then
  5527.     proceed with an optimised special case for those; otherwise proceed
  5528.     with the generic code.
  5529.  
  5530. \DOCMODE(
  5531. \xydef@\Directiontest@@#1#2{#2}
  5532.  
  5533. \xydef@\setupDirection@{%
  5534.  \dX=\Xc\advance\dX-\Xp \dY=\Yc\advance\dY-\Yp            %?*[Dir1]
  5535.  \Directiontest@@\relax\setupDirection@i}
  5536.  
  5537. \xydef@\setupDirection@i{\DN@{\setupDirection@ii}%        %?*[Diri1]
  5538.  \ifdim\dX=\dY
  5539.   \ifdim\dY=\z@ \DN@{}%
  5540.   \else\ifdim\dX<\z@ \DN@{\dlDirection@{-1.4142\dX}}%
  5541.   \else \DN@{\urDirection@{1.4142\dX}}\fi\fi
  5542.  \else\ifdim\dX<\dY
  5543.   \ifdim\dX=\z@ \DN@{\uDirection@\dY}%
  5544.   \else\ifdim\dY=\z@ \DN@{\lDirection@{-\dX}}%
  5545.   \else\ifdim-\dX=\dY \DN@{\ulDirection@{-1.4142\dX}}\fi\fi\fi
  5546.  \else
  5547.   \ifdim\dX=\z@ \DN@{\dDirection@{-\dY}}%
  5548.   \else\ifdim\dY=\z@ \DN@{\rDirection@\dX}%
  5549.   \else\ifdim\dX=-\dY \DN@{\drDirection@{1.4142\dX}}\fi\fi\fi
  5550.  \fi\fi \next@}
  5551. \DOCMODE)
  5552.  
  5553.     The procedures for the special <diag>onal cases are summarised in
  5554.     this table:
  5555. $$
  5556. \let\|=\otherbar
  5557. \begin{array}{\|c\|r\|rl\|c\|rl\|}
  5558. \hline
  5559. \mbox{<diag>onal} & "Direction" & \cos("Direction"),& \sin("Direction")
  5560.     & "sign"("dX","dY") & "Char" & "Semi" \\
  5561. \hline
  5562.  |dl| &     0 & {-\sqrt{\frac12}},& {-\sqrt{\frac12}} & -,- & 127 & 127 \\
  5563.  |d|  &     K &             0,& -1           & +,- &  15 & 31  \\
  5564.  |dr| & 2K &  {\sqrt{\frac12}},& {-\sqrt{\frac12}} & +,- &  31 & 63  \\
  5565.  |r|  & 3K &             1,& 0           & +,+ &  47 & 95  \\
  5566.  |ur| & 4K &  {\sqrt{\frac12}},& {\sqrt{\frac12}}  & +,+ &  63 & 127 \\
  5567.  |u|  &-3K &             0,& 1           & +,+ &  79 & 31  \\
  5568.  |ul| &-2K & {-\sqrt{\frac12}},& {\sqrt{\frac12}}  & -,+ &  95 & 63  \\
  5569.  |l|  & -K &            -1,& 0           & -,+ & 111 & 95  \\
  5570. \hline
  5571. \end{array}
  5572. $$
  5573.     In each case the argument is used as the unit circle, \ie, non-zero
  5574.     of "dX" and "dY", and $|<|K\frac{"dX"}{"dY"}|,|K\frac{"dY"}{"dX"}|>|
  5575.     := "KK"*|<|"dX"|,|"dY"|>|$\dots
  5576.  
  5577. \DOCMODE(
  5578. \xydef@\dlDirection@{\Direction=\z@
  5579.  \def\cosDirection{-.7071}\def\sinDirection{-.7071}\def\sdX{-}\def\sdY{-}%
  5580.  \chardef\DirectionChar=127\relax\chardef\SemiDirectionChar=127\relax
  5581.  \K@dXdY=1\K \K@dYdX=1\K \fixedDirection@}
  5582.  
  5583. \xydef@\dDirection@{\Direction=\K
  5584.  \def\cosDirection{0}\def\sinDirection{-1}\def\sdX{+}\def\sdY{-}%
  5585.  \chardef\DirectionChar=15\relax\chardef\SemiDirectionChar=31\relax
  5586.  \K@dXdY=\z@ \K@dYdX=\KK@\K \fixedDirection@}
  5587.  
  5588. \xydef@\drDirection@{\dimen@ii=2\K \Direction=\dimen@ii
  5589.  \def\cosDirection{+.7071}\def\sinDirection{-.7071}\def\sdX{+}\def\sdY{-}%
  5590.  \chardef\DirectionChar=31\relax\chardef\SemiDirectionChar=63\relax
  5591.  \K@dXdY=-1\K \K@dYdX=-1\K \fixedDirection@}
  5592.  
  5593. \xydef@\rDirection@{\dimen@ii=3\K \Direction=\dimen@ii
  5594.  \def\cosDirection{+1}\def\sinDirection{0}\def\sdX{+}\def\sdY{+}%
  5595.  \chardef\DirectionChar=47\relax\chardef\SemiDirectionChar=95\relax
  5596.  \K@dXdY=\KK@\K \K@dYdX=\z@ \fixedDirection@}
  5597.  
  5598. \xydef@\urDirection@{\dimen@ii=4\K \Direction=\dimen@ii
  5599.  \def\cosDirection{+.7071}\def\sinDirection{+.7071}\def\sdX{+}\def\sdY{+}%
  5600.  \chardef\DirectionChar=63\relax\chardef\SemiDirectionChar=127\relax
  5601.  \K@dXdY=1\K \K@dYdX=1\K \fixedDirection@}
  5602.  
  5603. \xydef@\uDirection@{\dimen@ii=-3\K \Direction=\dimen@ii
  5604.  \def\cosDirection{0}\def\sinDirection{+1}\def\sdX{+}\def\sdY{+}%
  5605.  \chardef\DirectionChar=79\relax\chardef\SemiDirectionChar=31\relax
  5606.  \K@dXdY=\z@ \K@dYdX=\KK@\K \fixedDirection@}
  5607.  
  5608. \xydef@\ulDirection@{\dimen@ii=-2\K \Direction=\dimen@ii
  5609.  \def\cosDirection{-.7071}\def\sinDirection{+.7071}\def\sdX{-}\def\sdY{+}%
  5610.  \chardef\DirectionChar=95\relax\chardef\SemiDirectionChar=63\relax
  5611.  \K@dXdY=-1\K \K@dYdX=-1\K \fixedDirection@}
  5612.  
  5613. \xydef@\lDirection@{\Direction=-\K
  5614.  \def\cosDirection{-1}\def\sinDirection{0}\def\sdX{-}\def\sdY{+}%
  5615.  \chardef\DirectionChar=111\relax\chardef\SemiDirectionChar=95\relax
  5616.  \K@dXdY=\KK@\K \K@dYdX=\z@ \fixedDirection@}
  5617.  
  5618. \xydef@\fixedDirection@#1{\dimen@ii=#1\relax
  5619.  \dX=\cosDirection\dimen@ii \dY=\sinDirection\dimen@ii
  5620.  \resetupDirection@}
  5621. \DOCMODE)
  5622.  
  5623.     Here is the procedure for the generic code.
  5624. %
  5625. \begin{itemize}
  5626. \item[{??_[Dirii1]}]
  5627.     Make sign variables and slopes: $"sdX" := "sign"("dX")$, $"sdY" :=
  5628.     "sign"("dY")$, $K\frac{"dX"}{"dY"} :=
  5629.     "sdX"*"sdY"*\floor{\abs{"KK"*"dX"} / \abs{"dY"/"KK"}}$, and
  5630.     $K\frac{"dY"}{"dX"} := "sdX"*"sdY"*\floor{\abs{"KK"*"dY"} /
  5631.     \abs{"dX"/"KK"}}$, where the somewhat exotic computation method is
  5632.     used to ensure that the `native' floor function provided by \TeX\
  5633.     |\divide| can be used (it only acts predictably for positive
  5634.     numbers), that overflow is avoided even for large $"dX","dY"$, and
  5635.     that it is reasonable to use the convention of |\quotient@| that
  5636.     division by zero is like multiplying with one\dots Also takes care
  5637.     not to multiply to big dimensions with each other.
  5638.  
  5639. \item[{??_[Dirii2]}]
  5640.     If ${-K} \le K\frac{"dX"}{"dY"} \le K$ then the direction is mostly
  5641.     up or down: if $"dY"\lt0$ [down, ??_[Dirii2a]]: $"Direction" := -
  5642.     K\frac{"dX"}{"dY"} + 1K$; else [up, ??_[Dirii2b]]: $"Direction" := -
  5643.     K\frac{"dX"}{"dY"} - 3K$.
  5644.  
  5645. \item[{??_[Dirii3]}]
  5646.     If ${-K} \lt K\frac{"dY"}{"dX"} \lt K$ then direction is mostly left
  5647.     or right: if $"dX"\lt0$ [left, ??_[Dirii3a]]: $"Direction" :=
  5648.     K\frac{"dY"}{"dX"} - K$; else [right, ??_[Dirii3b]]: $"Direction" :=
  5649.     K\frac{"dY"}{"dX"} + 3K$.
  5650.  
  5651. \item[{??_[Dirii4]}]
  5652.     Compute character codes for direction and semidirection fonts.
  5653.     [??_[Dirii4a]]: $"DirectionChar" := (8K+"Direction"+K/32)
  5654.     \hbox{~div~} (K/16) - 1$; while $"DirectionChar" \gt 127:
  5655.     "DirectionChar" -:= 128$.  [??_[Dirii4b]]: $"SemiDirectionChar" :=
  5656.     (8K+"Direction"+K/64) \hbox{~div~} (K/32) - 1$; while
  5657.     $"SemiDirectionChar" \gt 127: "SemiDirectionChar" -:= 128$. In both
  5658.     cases the $8K$ are added to ensure that \TeX\ will round down.
  5659.     \HACK: The |16|, |\KK@|, and |64| in these lines are really $K/64$,
  5660.     $K/32$, and $K/16$\dots
  5661.  
  5662. \item[{??_[Dirii5]}]
  5663.     Build "cosDirection" and "sinDirection" from appropriate characters
  5664.     in the |\xydashfont|. [??_[Dirii5]]: $"cosDirection" :=
  5665.     "wd"(|\xydashfont| "SemiDirectionChar")$.  [??_[Dirii5b]] $C :=
  5666.     "SemiDirectionChar"-64$, if $C\lt0$: $C := C+128$, $"sinDirection" :=
  5667.     "wd"(|\xydashfont| C)$.
  5668.  
  5669. \item[{??_[Dirii6]}]
  5670.     Register this "dX","dY" for next time.
  5671.  
  5672. \end{itemize}
  5673.  
  5674. \DOCMODE(
  5675. \xydef@\setupDirection@ii{%
  5676.  \ifdim\dX<\z@ \def\sdX{-}\else \def\sdX{+}\fi            %?*[Dirii1]
  5677.  \ifdim\dY<\z@ \def\sdY{-}\else \def\sdY{+}\fi
  5678.  \K@dXdY=\sdX\dX \ifdim\K@dXdY<500pt \multiply\K@dXdY\KK@ \fi \dimen@=\sdY\dY
  5679.   \advance\dimen@.5\KK@ \divide\dimen@\KK@
  5680.  \ifdim\dimen@=\z@\else %\count@=\dimen@ \divide\count@\tw@
  5681.   \advance\K@dXdY by.5\dimen@\relax \divide\K@dXdY\dimen@
  5682.  \fi \K@dXdY=\sdX\sdY\K@dXdY
  5683.  \K@dYdX=\sdY\dY \ifdim\K@dYdX<500pt \multiply\K@dYdX\KK@ \fi \dimen@=\sdX\dX
  5684.   \advance\dimen@.5\KK@ \divide\dimen@\KK@
  5685.  \ifdim\dimen@=\z@\else %\count@=\dimen@ \divide\count@\tw@
  5686.   \advance\K@dYdX by.5\dimen@\relax \divide\K@dYdX\dimen@
  5687.  \fi \K@dYdX=\sdX\sdY\K@dYdX
  5688.  \Direction=\maxdimen
  5689.  \ifnum\K@dXdY<-\K \else \ifnum\K<\K@dXdY \else            %?*[Dirii2]
  5690.    \ifdim \dY<\z@                        %?*[Dirii2a]
  5691.     \Direction=\K \advance\Direction-\K@dXdY
  5692.    \else                            %?*[Dirii2b]
  5693.     \Direction=\K \multiply\Direction-\thr@@ \advance\Direction-\K@dXdY
  5694.  \fi\fi\fi
  5695.  \ifnum-\K<\K@dYdX \ifnum\K@dYdX<\K                %?*[Dirii3]
  5696.    \ifdim \dX<\z@                        %?*[Dirii3a]
  5697.     \Direction=-\K \advance\Direction\K@dYdX
  5698.    \else                            %?*[Dirii3b]
  5699.     \Direction=\K \multiply\Direction\thr@@ \advance\Direction\K@dYdX
  5700.  \fi\fi\fi
  5701.  \ifnum\Direction=\maxdimen
  5702.   \Direction=\K@dYdX \advance\Direction-\K@dXdY \divide\Direction\tw@ 
  5703.   \ifnum\K@dXdY<\z@ \advance\Direction\K \advance\Direction\K
  5704.   \else \advance\Direction-\K \advance\Direction-\K \fi
  5705.  \fi
  5706.  \count@@=\K \multiply\count@@ by8 \advance\count@@\Direction    %?*[Dirii4]
  5707.  \count@=\count@@ \advance\count@\KK@ \divide\count@64 \advance\count@\m@ne %?*[Dirii4a]
  5708.  \loop@\ifnum127<\count@ \advance\count@-128 \repeat@
  5709.  \chardef\DirectionChar\count@
  5710.  \advance\count@@16 \divide\count@@\KK@ \advance\count@@\m@ne    %?*[Dirii4b]
  5711.  \loop@\ifnum127<\count@@ \advance\count@@-128 \repeat@
  5712.  \chardef\SemiDirectionChar\count@@
  5713.  \setbox8=\hbox{\xydashfont\SemiDirectionChar\/}%        %?*[Dirii5]
  5714.  \quotient@@\cosDirection{\sdX\wd8}\xydashl@
  5715.  \setbox8=\hbox{\xydashfont\count@=\SemiDirectionChar\advance\count@-64 %?*[Dirii5b]
  5716.   \ifnum\count@<\z@ \advance\count@128 \fi \char\count@\/}%
  5717.  \quotient@@\sinDirection{\sdY\wd8}\xydashl@
  5718.  \resetupDirection@                        %?*[Dirii6]
  5719. }
  5720. \DOCMODE)
  5721.  
  5722.     Finally some special cases used by the <direction>s and directional
  5723.     library objects.  All manipulate the Direction dependent parameters
  5724.     and then call |\resetupDirection@|: |\reverseDirection| reverses it;
  5725.     |\above|- and |\belowDirection@| are for |^| and |_|, and
  5726.     $|\vDirection@(|x|,|y|){|L|}|$ is for $|:(|x|,|y|)|$, \ie, computes
  5727.     a new direction as the vector
  5728. $$
  5729.  |<|    X - x*\cos\alpha*L - y*({-}\sin\alpha)*L |,|
  5730.     Y - x*\sin\alpha*L - y*\cos\alpha*L |>|
  5731. $$
  5732.     where $\alpha$ is the previous direction angle.
  5733.  
  5734. \DOCMODE(
  5735. \xydef@\reverseDirection@{%
  5736.  \dX=-\dX \dY=-\dY
  5737.  \ifdim\dX<\z@ \def\sdX{-}\else \def\sdX{+}\fi
  5738.  \ifdim\dY<\z@ \def\sdY{-}\else \def\sdY{+}\fi
  5739.  \dimen@=4\K \ifnum\Direction<\z@ \advance\Direction\dimen@
  5740.   \else \advance\Direction-\dimen@ \fi
  5741.  \count@=\DirectionChar \ifnum\count@<64 \advance\count@64 %
  5742.   \else \advance\count@-64 \fi \chardef\DirectionChar=\count@
  5743.  \edef\cosDirection{\if-\cosDirection\else-\cosDirection\fi}%
  5744.  \edef\sinDirection{\if-\sinDirection\else-\sinDirection\fi}%
  5745.  \resetupDirection@}
  5746.  
  5747. \xydef@\aboveDirection@#1{%
  5748.  \dimen@=\dX \dX=-\dY \dY=\dimen@
  5749.  \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
  5750.  \ifdim\dX<\z@ \def\sdX{-}\else \def\sdX{+}\fi
  5751.  \ifdim\dY<\z@ \def\sdY{-}\else \def\sdY{+}\fi
  5752.  \dimen@=2\K \ifdim 1\Direction<\dimen@\else \dimen@=-6\K \fi
  5753.   \advance\Direction\dimen@
  5754.  \count@=\DirectionChar \ifnum\count@<96 \advance\count@32 %
  5755.   \else \advance\count@-96 \fi \chardef\DirectionChar=\count@
  5756.  \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64 %
  5757.   \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
  5758.  \let\tmp@=\cosDirection
  5759.  \edef\cosDirection{\if-\sinDirection\else-\sinDirection\fi}%
  5760.  \let\sinDirection=\tmp@
  5761.  \dimen@=#1\relax \dX=\cosDirection\dimen@ \dY=\sinDirection\dimen@
  5762.  \resetupDirection@}
  5763.  
  5764. \xydef@\belowDirection@#1{%
  5765.  \dimen@=\dX \dX=\dY \dY=-\dimen@
  5766.  \dimen@=\K@dXdY \K@dXdY=-\K@dYdX \K@dYdX=-\dimen@
  5767.  \ifdim\dX<\z@ \def\sdX{-}\else \def\sdX{+}\fi
  5768.  \ifdim\dY<\z@ \def\sdY{-}\else \def\sdY{+}\fi
  5769.  \dimen@=-2\K\ifdim 1\Direction<\dimen@\dimen@=6\K\fi \advance\Direction\dimen@
  5770.  \count@=\DirectionChar \ifnum\count@<32 \advance\count@96 %
  5771.   \else \advance\count@-32 \fi \chardef\DirectionChar=\count@
  5772.  \count@=\SemiDirectionChar \ifnum\count@<64 \advance\count@64 %
  5773.   \else \advance\count@-64 \fi \chardef\SemiDirectionChar=\count@
  5774.  \let\tmp@=\sinDirection
  5775.  \edef\sinDirection{\if-\cosDirection\else-\cosDirection\fi}%
  5776.  \let\cosDirection=\tmp@
  5777.  \dimen@=#1\relax \dX=\cosDirection\dimen@ \dY=\sinDirection\dimen@
  5778.  \resetupDirection@}
  5779.  
  5780. \xydef@\vDirection@(#1,#2)#3{\dimen@ii=#3\relax
  5781.  \dimen@=#1\dimen@ii \dimen@ii=#2\dimen@ii
  5782.  \dX=\cosDirection\dimen@ \advance\dX-\sinDirection\dimen@ii
  5783.  \dY=\sinDirection\dimen@ \advance\dY \cosDirection\dimen@ii
  5784.  \Xp=\Xc \advance\Xp-\dX \Yp=\Yc \advance\Yp-\dY
  5785.  \setupDirection@\ignorespaces}
  5786. \DOCMODE)
  5787.  
  5788.     The above all make use of the following; use them also when the
  5789.     direction state is known to be correct: |\resetDirection@| should be
  5790.     called when $p$ and/or $c$ are moved along the line $\vec{pc}$,
  5791.     |\resetupDirerection| when the entire direction state is changed in a
  5792.     consistent manner.
  5793.  
  5794. \DOCMODE(
  5795. \xydef@\resetDirection@{%
  5796.  \dX=\Xc\advance\dX-\Xp \dY=\Yc\advance\dY-\Yp \let\next@=\resetupDirection@
  5797.  \ifdim\sdX\dX<\z@ \let\next@=\setupDirection@i \fi
  5798.  \ifdim\sdY\dY<\z@ \let\next@=\setupDirection@i \fi
  5799.  \next@}
  5800.  
  5801. \xydef@\resetupDirection@{%
  5802.  \edef\Directiontest@@##1##2{\noexpand\DN@{##2}%
  5803.   \noexpand\ifdim\noexpand\dX=\the\dX\relax
  5804.    \noexpand\ifdim\noexpand\dY=\the\dY\relax \noexpand\DN@{##1}%
  5805.   \noexpand\fi\noexpand\fi \noexpand\next@}}
  5806.  
  5807. \xydef@\unsetupDirection@{\def\Directiontest@@##1##2{##2}}
  5808. \DOCMODE)
  5809.  
  5810.     Finally the initial direction: up!
  5811.  
  5812. \DOCMODE(
  5813. \uDirection@\xydashl@
  5814. \DOCMODE)
  5815.  
  5816. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5817.  
  5818.  
  5819. \subsection{Edges}
  5820. ??=[algo.edge]
  5821.  
  5822.     An "Edge" is a token list describing the edge of an object.  It must
  5823.     have the form |{|<expandable token> <unexpandable tokens>|}|.
  5824.     To find the edge of an object then first make it the current object
  5825.     and then do
  5826. $$
  5827.  |\the\Edgec|<code>
  5828. $$
  5829.     where <code> determines what should be done:
  5830. %
  5831. \begin{itemize}
  5832.  
  5833. \item[0]
  5834.     $c$ is changed to be equal to the point on the edge intersecting with
  5835.     the line segment from $p$ (this is the v2.6 behaviour).
  5836.  
  5837.     \NOTE: This should not change any of $A$, $B$, or any component of
  5838.     the state except $X_c$ and $Y_c$!
  5839.  
  5840. \item[1]
  5841.     Test whether the center of $p$, \ie, $|<|X_p|,|Y_p|>|$, is `inside'
  5842.     the $c$ object (or on the edge).  Sets the test |\ifInside@|
  5843.     accordingly.
  5844.  
  5845. \item[2]
  5846.     Set |\dimen@| to the distance from the center to the edge towards~$p$
  5847.     (as set with code~0).
  5848.  
  5849.     \NOTE: This is only positive in the direction towards $p$
  5850.     (thus negative-sized circles and rectangles make it negative).
  5851.  
  5852. \item[3]
  5853.     $c$ is changed to be equal to the point on the edge furthest in the
  5854.     direction towards $p$.
  5855.  
  5856.     \NOTE: This should not change any of $A$, $B$, or any component of
  5857.     the state except $X_c$ and $Y_c$!
  5858.  
  5859. \item[4]
  5860.     Replace $c$ with rectangle with corners where the line from $p$
  5861.     intersects with the edge of $c$ (thus this is the inner rectangle
  5862.     with corners as the current direction dictates).
  5863.  
  5864. \item[5]
  5865.     Replace $c$ with smallest rectangle that encloses the current object
  5866.     completely.
  5867.  
  5868. \end{itemize}
  5869. %
  5870.     (if this reminds the reader of a `dictionary' as used by
  5871.     object-oriented programming languages then they probably share this
  5872.     authors regret that \TeX\ is not object oriented :-)
  5873.  
  5874. \DOCMODE(
  5875. \message{edges,}
  5876.  
  5877. \xynew@{if}\ifInside@
  5878. \DOCMODE)
  5879.  
  5880. \paragraph*{Points:}
  5881.  
  5882.     The simplest shape is none at all -- a point.
  5883.  
  5884. \DOCMODE(
  5885. \xydef@\zeroEdge#1{%
  5886.  \ifcase#1\relax \or \Inside@false \or \dimen@=\z@
  5887.  \or \or \else \Edgec={\rectangleEdge}\fi}
  5888. \DOCMODE)
  5889.  
  5890. \paragraph*{Circles:}
  5891.  
  5892.     Next we define round things: Code~0 moves $|<|X_c|,|Y_c|>|$ to    the
  5893.     point $|<|X_c - R_c*\cos\alpha|,| Y_c - R_c*\sin\alpha|>|$ where
  5894.     $\alpha$ is the current direction angle, code~1 tests whether the
  5895.     $p$ center is located between those two points., code~2 just returns
  5896.     the radius, code~3 is as code~0 and code~4 is the only nontrivial
  5897.     one, replacing with the inner symmetric rectangle with corner at the
  5898.     point of code~0.
  5899.  
  5900. \DOCMODE(
  5901. \xydef@\circleEdge#1{\ifcase#1\expandafter\circleEdge@
  5902.  \or \expandafter\circleUnder@ \or \dimen@=\Rc
  5903.  \or \expandafter\circleEdge@ \or \expandafter\circleInner@
  5904.  \else \expandafter\circleOuter@ \fi}
  5905.  
  5906. \xydef@\circleEdge@{%
  5907.  \dimen@=-\cosDirection\Rc \advance\Xc\dimen@
  5908.  \dimen@=-\sinDirection\Rc \advance\Yc\dimen@}
  5909.  
  5910. %\xydef@\circleUnder@{\Inside@false
  5911. % \ifdim\Xp=\Xc \ifdim\Yp=\Yc \Inside@true \fi\fi 
  5912. % \ifInside@ \else{\setupDirection@
  5913. %  \dimen@=\cosDirection\Rc \dimen@=\sdX\dimen@
  5914. %  \dimen@ii=\sinDirection\Rc \dimen@ii=\sdY\dimen@ii
  5915. %  \ifdim\dimen@>\dimen@ii
  5916. %   \ifdim\sdX\dX<\dimen@\aftergroup\Inside@true\fi
  5917. %  \else
  5918. %   \ifdim\sdY\dY<\dimen@ii\aftergroup\Inside@true\fi
  5919. %  \fi}\fi }
  5920.  
  5921. \xydef@\circleUnder@{\Inside@false
  5922.  \ifdim\Xp=\Xc \relax \ifdim\Yp=\Yc \Inside@true \fi \fi 
  5923.  \ifInside@ \else \expandafter \circleCentre@ \fi }
  5924.  
  5925. \xydef@\circleCentre@{{%
  5926.  \ifdim\Lc=\Rc \relax\else
  5927.   \dimen@=\Rc\advance\dimen@-\Lc \divide\dimen@\tw@
  5928.   \advance\Xc\dimen@ \advance\Rc-\dimen@ \fi
  5929.  \dX=\Xc \advance\dX-\Xp \dX=\ifdim\dX<\z@-\fi\dX
  5930.  \ifdim\Uc=\Dc\relax \else
  5931.   \dimen@=\Uc\advance\dimen@-\Dc \divide\dimen@\tw@
  5932.   \advance\Yc\dimen@ \advance\Uc-\dimen@ \fi
  5933.  \dY=\Yc \advance\dY-\Yp \dY=\ifdim\dY<\z@-\fi\dY
  5934.  \DN@{}\ifdim\dX>\Rc \relax \else \ifdim\dY>\Uc \relax 
  5935.   \else \ifdim\Uc=\Rc \DN@{\circleUnder@@}%
  5936.   \else \DN@{\ellipseUnder@@}\fi
  5937.  \fi\fi \next@ }}
  5938.  
  5939. \xydef@\circleUnder@@{%
  5940.  \loop\ifdim\Rc>100\p@ \circlescale@ \repeat
  5941.  \edef\tmp@{\expandafter\removePT@\the\Rc}\dimen@=\tmp@\Rc 
  5942.  \edef\tmp@{\expandafter\removePT@\the\dX}\advance\dimen@-\tmp@\dX
  5943.  \edef\tmp@{\expandafter\removePT@\the\dY}\advance\dimen@-\tmp@\dY
  5944.  \ifdim\dimen@>\z@ \aftergroup\Inside@true \fi }
  5945.  
  5946. \xydef@\circlescale@{\divide\Rc\KK@ \divide\dX\KK@ \divide\dY\KK@ }
  5947.  
  5948. \xydef@\ellipseUnder@@{%
  5949.  \ifdim\Rc>64\p@ \circlescale@ \divide\Uc\KK@ 
  5950.  \else \ifdim\Uc>64\p@ \circlescale@ \divide\Uc\KK@ \fi\fi
  5951.  \edef\tmp@{\expandafter\removePT@\the\Rc}\dY=\tmp@\dY 
  5952.  \edef\tmp@{\expandafter\removePT@\the\Uc}\dX=\tmp@\dX 
  5953.  \Rc=\tmp@\Rc \circleUnder@@ }
  5954.  
  5955. \xydef@\circleInner@{%
  5956.  \Lc=\sdX\cosDirection\Rc \Dc=\sdY\sinDirection\Rc
  5957.  \Rc=\Lc \Uc=\Dc \Edgec={\rectangleEdge}}
  5958.  
  5959. \xydef@\circleOuter@{%
  5960.  \Lc=\Rc \Dc=\Rc \Uc=\Dc \Edgec={\rectangleEdge}}
  5961. \DOCMODE)
  5962.  
  5963.     \BUG: It is assumed that the circle has reference point in its
  5964.     center; the radius is taken directly from $R_c$.
  5965.  
  5966. \paragraph*{Rectangles:}\leavevmode
  5967.  
  5968.     Rectangles intersection is slightly more complicated and handled
  5969.     separately for the horizontal and vertical case.
  5970.  
  5971. \DOCMODE(
  5972. \xydef@\rectangleEdge#1{\ifcase#1\expandafter\rectangleEdge@
  5973.  \or \expandafter\rectangleUnder@ \or \expandafter\rectangleWidth@
  5974.  \or \expandafter\rectangleProp@
  5975.  \else \relax \fi}
  5976. \DOCMODE)
  5977.  
  5978. \DOCMODE(
  5979. % \rectangleEdge@
  5980. %    Sets <X,Y> to the intersection of a line from <X-dX,Y-dY> to <X,Y>
  5981. %    and the rectangle from <X-L,Y-D> to <X+R,Y+U>:
  5982. %
  5983. %    %1a    dY<0, dX<0:    X := X + min{R, U*|dX/dY|},
  5984. %                Y := Y + min{U, R*|dY/dX|};
  5985. %      b    dY<0, dX=0:    Y := Y + U;
  5986. %      c    dY<0, dX>0:    X := X - min{L, U*|dX/dY|},
  5987. %                Y := Y + min{U, L*|dY/dX|};
  5988. %
  5989. %    %2a    dY=0, dX<0:    X := X + R;
  5990. %      b    dY=0, dX=0:    ;
  5991. %      c    dY=0, dX>0:    X := X - L;
  5992. %
  5993. %    %3a    dY>0, dX<0:    X := X + min{R, D*|dX/dY|},
  5994. %                Y := Y - min{D, R*|dY/dX|};
  5995. %      b    dY>0, dX=0:    Y := Y - D;
  5996. %      c    dY>0, dX>0:    X := X - min{L, D*|dX/dY|},
  5997. %                Y := Y - min{D, L*|dY/dX|};
  5998. %
  5999. %    %4 \resetupDirection@ to register that even though dX,dY changed all
  6000. %       Direction parameters are is still valid!
  6001. %
  6002. %    NOTE: d=0 really means |d| < .05pt.
  6003. %
  6004. \xydef@\rectangleEdge@{%
  6005.  \ifdim\dY<-.05\p@ \rectangleEdge@i                    %1
  6006.  \else\ifdim\dY<.05\p@ \rectangleEdge@ii                %2
  6007.  \else \rectangleEdge@iii\fi\fi
  6008.  \resetupDirection@}
  6009.  
  6010. \xydef@\rectangleEdge@i{%
  6011.  \ifdim\dX<-.05\p@ \settomin@\Xc+\Rc\Uc\dX\dY \settomin@\Yc+\Uc\Rc\dY\dX%1a
  6012.  \else\ifdim\dX<.05\p@ \advance\Yc\Uc                    %1b
  6013.  \else \settomin@\Xc-\Lc\Uc\dX\dY \settomin@\Yc+\Uc\Lc\dY\dX        %1c
  6014.  \fi\fi}
  6015.  
  6016. \xydef@\rectangleEdge@ii{%
  6017.  \ifdim\dX<-.05\p@ \advance\Xc\Rc                    %2a
  6018.  \else\ifdim\dX<.05\p@                            %2b
  6019.  \else \advance\Xc-\Lc                            %2c
  6020.  \fi\fi}
  6021.  
  6022. \xydef@\rectangleEdge@iii{%
  6023.  \ifdim\dX<-.05\p@ \settomin@\Xc+\Rc\Dc\dX\dY \settomin@\Yc-\Dc\Rc\dY\dX%3a
  6024.  \else\ifdim\dX<.05\p@ \advance\Yc-\Dc                    %3b
  6025.  \else \settomin@\Xc-\Lc\Dc\dX\dY \settomin@\Yc-\Dc\Lc\dY\dX        %3c
  6026.  \fi\fi}
  6027.  
  6028. \xydef@\settomin@#1#2#3#4#5#6{%
  6029.  % Perform d := #2 min{#3, #4*|#5/#6|}; #1 := #1+d ...
  6030.  \edef\nextii@{\A@=\the\A@ \B@=\the\B@}\quotient@\next@{#5}{#6}\nextii@
  6031.  \dimen@=\sdX\sdY\next@#4\relax
  6032.  \ifdim#3<\dimen@ \dimen@=#3\fi \advance#1#2\dimen@}
  6033. \DOCMODE)
  6034.  
  6035.     Checking that $p$ is under is simpler:
  6036.  
  6037. \DOCMODE(
  6038. \xydef@\rectangleUnder@{\Inside@false
  6039.  \ifdim\Xp=\Xc \ifdim\Yp=\Yc \Inside@true \fi\fi 
  6040.  \ifInside@ \else
  6041.   \dimen@=\Xp \advance\dimen@-\Xc 
  6042.   \ifdim \dimen@>-\Lc \relax \ifdim\dimen@<\Rc 
  6043.    \dimen@=\Yp \advance\dimen@-\Yc 
  6044.    \ifdim \dimen@>-\Dc \relax \ifdim\dimen@<\Uc 
  6045.     \Inside@true 
  6046.  \fi\fi\fi\fi\fi }
  6047. \DOCMODE)
  6048.  
  6049.     Calculating the width is like computing the edge point just simpler:
  6050.  
  6051. \DOCMODE(
  6052. \xydef@\rectangleWidth@{\let\next@=\rectangleWidth@i
  6053.  \ifdim\dX<-.05\p@ \A@=\Rc
  6054.  \else\ifdim\dX<.05\p@ \A@=\z@ \DN@{\dimen@=\B@}%
  6055.  \else \A@=\Lc \fi\fi
  6056.  \ifdim\dY<-.05\p@ \B@=\Uc
  6057.  \else\ifdim\dY<.05\p@ \DN@{\dimen@=\A@}%
  6058.  \else \B@=\Dc \fi\fi
  6059.  \next@}
  6060.  
  6061. \xydef@\rectangleWidth@i{%
  6062.  \begingroup
  6063.   \dimen@=\sdX\cosDirection\B@
  6064.   \quotient@\next\dimen@{\sdY\sinDirection\p@}\dimen@=\next\dimen@
  6065.   \edef\next{\endgroup \dimen@=\the\dimen@}%
  6066.  \ifdim\dimen@<\B@ \B@=\the\dimen@ \fi
  6067.  \begingroup
  6068.   \dimen@=\sdY\sinDirection\A@
  6069.   \quotient@\next\dimen@{\sdX\cosDirection\p@}\dimen@=\next\dimen@
  6070.   \edef\next{\endgroup \dimen@=\the\dimen@}%
  6071.  \ifdim\dimen@<\A@ \A@=\the\dimen@ \fi
  6072.  \dimen@=\sdX\cosDirection\A@ \advance\dimen@\sdY\sinDirection\B@}
  6073. \DOCMODE)
  6074.  
  6075.     Setting $c$ to the `proportional edge point' is straight out of
  6076.     v2.6's |\setlabel@@| macro\dots
  6077.  
  6078. \DOCMODE(
  6079. % First rotate to opposite direction.
  6080.  
  6081. % Then compute Leftf,Upf [\next@,\nextii@]:
  6082. %        0,(D-2K)/2K    for  2K < D <= 4K    [right]
  6083. %    (2K-D)/2K,0        for   0 < D <= 2K    [down]
  6084. %        1,-D/2K        for -2K < D <= 0    [left]
  6085. %    (D+4K)/2K,1        for -4K < D <= -2K    [up]
  6086.  
  6087. % Finally set <X,Y> to
  6088. %    < X - L + Leftf*(R+L) , Y + U - Upf*(D+U) >
  6089.  
  6090. \xydef@\rectangleProp@{%
  6091. %
  6092.  \enter@{\A@=\the\A@ \B@=\the\B@ \DirectionfromtheDirection@}%
  6093. %
  6094. % \count@@@=\Direction
  6095. % \dimen@=4\K \ifnum\count@>\z@ \advance\count@@@-\dimen@
  6096. %  \else \advance\count@@@\dimen@ \fi
  6097. %
  6098.  \reverseDirection@
  6099. %
  6100.  \dimen@=1\Direction \count@=\K \multiply\count@\tw@
  6101.  \ifnum \Direction>\count@
  6102.   \DN@{0}%
  6103.   \advance\dimen@-2\K \quotient@\nextii@{\dimen@}{2\K}%
  6104.  \else\ifnum \Direction>\z@
  6105.   \dimen@=-\dimen@ \advance\dimen@2\K \quotient@\next@{\dimen@}{2\K}%
  6106.   \DNii@{0}%
  6107.  \else\ifnum \Direction>-\count@
  6108.   \DN@{1}%
  6109.   \quotient@\nextii@{-\dimen@}{2\K}%
  6110.  \else
  6111.   \advance\dimen@4\K \quotient@\next@{\dimen@}{2\K}%
  6112.   \DNii@{1}%
  6113.  \fi\fi\fi
  6114. %
  6115. % \advance\Xc-\Lc \dimen@=\Lc \advance\dimen@\Rc \advance\Xc\next@\dimen@
  6116. % \advance\Yc+\Uc \dimen@=\Dc \advance\dimen@\Uc \advance\Yc-\nextii@\dimen@
  6117.  \advance\Xc-\Lc \dimen@=\Lc \advance\dimen@\Rc 
  6118.   \ifdim\dimen@=\z@ \advance\Xc 2\Lc \else \advance\Xc\next@\dimen@ \fi
  6119.  \advance\Yc+\Uc \dimen@=\Dc \advance\dimen@\Uc 
  6120.   \ifdim\dimen@=\z@ \advance\Yc-2\Uc \advance\Yc\Upness@\Uc
  6121.   \else \advance\Yc-\nextii@\dimen@ \fi
  6122. %
  6123.  \leave@}
  6124. \DOCMODE)
  6125.  
  6126. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6127.  
  6128.  
  6129. \subsection{Connections}
  6130. ??=[algo.connection]
  6131.  
  6132.     \TODO: Complete conversion to |DOCMODE| form.
  6133.  
  6134. \DOCMODE(
  6135. \message{connections;}
  6136.  
  6137. % Connections describe how a particular OBJECT may be used to connect p to c.
  6138. % The following parameters are used:
  6139. %
  6140. %    Invisible@@, Hidden@@, Drop@@: from OBJECT.
  6141. %
  6142. %    lastobjectbox@: box to fill with; assumed to be `trimmed' to have
  6143. %        only the size needed for the filler; size is w*(h+d) (this is
  6144. %        handled, e.g., by the POS ** interpretion \connect@).
  6145. %
  6146. % and defines the following parameters in addition to actually typesetting
  6147. % the connection:
  6148. \DOCMODE)
  6149.  
  6150.     The following methods are defined by any connection; they should be
  6151.     used in the indicated sequence:??w[connection methods]
  6152.  
  6153. \begin{description}
  6154. \item[|\Creset@@|:]
  6155.     (Re)set the connection parameters to allow use of the following to
  6156.     move to a point on the connection (this is what the interpretation of
  6157.     <pos> |?| does first).
  6158.  
  6159. \item[|\Cshavep@@| or |\Cshavec@@|:]
  6160.     Move $p$ or $c$ to the start or finish of the connection.  These may
  6161.     be called several times or not at all.
  6162.  
  6163. \item[|\Calong@@{|<factor>|}|:]
  6164.     Move $c$ to point the <factor> along the connection and set the
  6165.     direction parameters as a tangent to it in this point.
  6166.  
  6167. \item[|\Cslidep@@{|<dimen>|}| or |\Cslidec@@{|<dimen>|}|:]
  6168.     Move $p$ or $c$ the <dimen>sion further in the current direction.
  6169.     Can be used both before and after the |\Calong@@| method.
  6170.  
  6171. \end{description}
  6172.  
  6173. \DOCMODE(
  6174. \xydef@\Creset@@{}
  6175. \xydef@\Cshavep@@{\noCshavep@@}
  6176. \xydef@\Cshavec@@{\noCshavec@@}
  6177. \xydef@\Cslidep@@{\noCslidep@@}
  6178. \xydef@\Cslidec@@{\noCslidec@@}
  6179. \xydef@\Calong@@{\noCalong@@}
  6180.  
  6181. % NOTE: Basic XY-pictures only have straight connections and thus the C* macros
  6182. % given here are rather simple...in particular you should not make use of the
  6183. % Direction parameters until after calling Calong@@{F}!
  6184.  
  6185. % \no@@
  6186. %    Dummy connection for use with OBJECTS where it just does not make
  6187. %    sense to build connections...or just setup a dummy straight
  6188. %    connection :-)
  6189.  
  6190. \xydef@\no@@{\setupDirection@
  6191.  \edef\Creset@@{\cfromthec@ \pfromthep@ \noexpand\setupDirection@}%
  6192.  \def\Cshavep@@{\noCshavep@@}\def\Cshavec@@{\noCshavec@@}%
  6193.  \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%
  6194.  \def\Calong@@{\noCalong@@}%
  6195.  \ifHidden@\else
  6196.   \ifdim\Yc>\Ymax \Ymax=\Yc \fi     \ifdim\Yp>\Ymax \Ymax=\Yp \fi
  6197.   \ifdim\Yc<\Ymin \Ymin=\Yc \fi     \ifdim\Yp<\Ymin \Ymin=\Yp \fi
  6198.   \ifdim\Xc>\Xmax \Xmax=\Xc \fi     \ifdim\Xp>\Xmax \Xmax=\Xp \fi
  6199.   \ifdim\Xc<\Xmin \Xmin=\Xc \fi     \ifdim\Xp<\Xmin \Xmin=\Xp \fi \fi}
  6200.  
  6201. \xydef@\noCshavep@@{\setupDirection@
  6202.  \enter@{\cfromthec@ \DirectionfromtheDirection@}%
  6203.  \reverseDirection@ \cfromp@ \the\Edgec\z@
  6204.  \pfromc@ \leave@ \resetDirection@}
  6205.  
  6206. \xydef@\noCshavec@@{\setupDirection@ \the\Edgec\z@ \resetDirection@}
  6207.  
  6208. \xydef@\noCslidep@@#1{\dimen@=#1\relax
  6209.  \advance\Xp\cosDirection\dimen@ \advance\Yp\sinDirection\dimen@
  6210.  \resetDirection@}
  6211.  
  6212. \xydef@\noCslidec@@#1{\dimen@=#1\relax
  6213.  \advance\Xc\cosDirection\dimen@ \advance\Yc\sinDirection\dimen@
  6214.  \resetDirection@}
  6215.  
  6216. \xydef@\noCalong@@#1{%
  6217.  \dX=#1\dX \dY=#1\dY \Xc=\Xp \Yc=\Yp \advance\Xc\dX \advance\Yc\dY
  6218.  \resetupDirection@}
  6219.  
  6220. % \straight@{SPREAD}
  6221. %    Build straight connection...using SPREAD to spread the fillers.
  6222.  
  6223. %    SPREAD: macro to expand *after* number of fillers N[\count@@] is
  6224. %        known; has A=w and B=d+h but *before* any filling is done.
  6225. %        May change N as well as dX,dY,X,Y,w,d,h in order to affect the
  6226. %        filling.
  6227.  
  6228. %    Procedure:
  6229. %    %1 setup Direction parameters now and define the Creset macros
  6230. %       to reestablish the initial state;
  6231.  
  6232. %    %2 build macro to discover if the edges of the objects overlap (it
  6233. %       just verifies that the signs of dX,dY did not change when the
  6234. %       edges were removed);
  6235.  
  6236. %    %3 move both p,c to the edges of the objects...and define the Cshave*
  6237. %       macros accordingly;
  6238.  
  6239. %    %4 choose either to ignore the connection if requested or there is
  6240. %       overlap between the objects of choose either vbox or hbox version
  6241. %       (see below)...
  6242.  
  6243. %    %5 build Calong@@ macro and reset pc.
  6244.  
  6245. % NOTE: Assumes that the Direction is not tampered with between Creset is
  6246. % defined and used...
  6247.  
  6248. \xydef@\Spread@@{}
  6249. \xydef@\checkoverlap@@{}
  6250.  
  6251. \xydef@\straight@#1{\setupDirection@ \def\Spread@@{#1}%            %1
  6252.  %
  6253.  \edef\Creset@@{\cfromthec@ \pfromthep@ \DirectionfromtheDirection@}%
  6254.  %
  6255.  \DN@##1##2{\def\checkoverlap@@{%                    %2
  6256.   \ifdim##1\Xp>##1\Xc \let\next@=\relax \fi
  6257.   \ifdim##2\Yp>##2\Yc \let\next@=\relax \fi}}%
  6258.  \edef\nextii@{{\sdX}{\sdY}}\expandafter\next@\nextii@
  6259.  %
  6260.  \noCshavep@@\edef\Cshavep@@{\pfromthep@ \noexpand\resetDirection@}%    %3
  6261.  \noCshavec@@\edef\Cshavec@@{\cfromthec@ \noexpand\resetDirection@}%
  6262.  %
  6263.  \ifHidden@\else                            %3b
  6264.   \ifdim\Yc>\Ymax \Ymax=\Yc \fi     \ifdim\Yp>\Ymax \Ymax=\Yp \fi
  6265.   \ifdim\Yc<\Ymin \Ymin=\Yc \fi     \ifdim\Yp<\Ymin \Ymin=\Yp \fi
  6266.   \ifdim\Xc>\Xmax \Xmax=\Xc \fi     \ifdim\Xp>\Xmax \Xmax=\Xp \fi
  6267.   \ifdim\Xc<\Xmin \Xmin=\Xc \fi     \ifdim\Xp<\Xmin \Xmin=\Xp \fi \fi
  6268.  %
  6269.  \ifInvisible@\let\next@=\relax                        %4
  6270.  \else\ifdim 1\Direction<-2\K \let\next@=\straightv@
  6271.  \else\ifdim 1\Direction<\z@ \let\next@=\straighth@
  6272.  \else\ifdim 1\Direction<2\K \let\next@=\straightv@
  6273.  \else \let\next@=\straighth@ \fi\fi\fi\fi
  6274.  \checkoverlap@@ \next@
  6275.  %
  6276.  \def\Cslidep@@{\noCslidep@@}\def\Cslidec@@{\noCslidec@@}%        %5
  6277.  \def\Calong@@{\noCalong@@}\Creset@@}
  6278.  
  6279. % Now for the works...to summarise: these are parametrised on Direction
  6280. % parameters and use
  6281.  
  6282. %    X,Y: endpoint of connection (`Direction end').
  6283. %    dX,dY: connection distance (`Direction vector').
  6284.  
  6285. %    Leftness@: from OBJECT.
  6286.  
  6287. %    lastobjectbox@: box to fill with; assumed to be `trimmed' to have
  6288. %        only the size needed for the filler; size is w*(h+d).
  6289.  
  6290. %    Spread@@: macro to expand to modify the default spreading used.
  6291.  
  6292. %    Drop@: macro to expand to actually typeset the finished connection
  6293. %        when it is in box0!  NOTE: Must make box0 void to avoid `box
  6294. %        leaks'.
  6295.  
  6296. % Using hbox:
  6297.  
  6298. %    %0 start box...
  6299.  
  6300. %    %1 compute initial adjustment (X  right and Y up) and...
  6301. %        A := w, B := h+d, N [\count@@] = floor(|dX| / A),
  6302. %       and run user supplied Spread;
  6303.  
  6304. %    %2 adjust first filler position horizontally:
  6305. %        if dX>0 then X := X-w;
  6306.  
  6307. %    %4 adjust first filler vertically:
  6308. %        Y := Y - sdX*L*(dY/dX)*w
  6309. %        where L = if dX>0 then (1-Leftness) else Leftness;
  6310.  
  6311. %    %3 recompute the move dimensions (A right and B up):
  6312. %        A := -sdX(|dX| - w) / (N-1),
  6313. %        B := sdY|sdX(w)*dY/dX - dY| / (N-1),
  6314. %       and set the filler box to have w := A;
  6315.  
  6316. %    %5 output first filler adjusted X,Y and the following N-1 each A
  6317. %       further right and raised B more than the previous;
  6318.  
  6319. % ...and finally end object with usual bravour!
  6320.  
  6321. \xydef@\straighth@{\setbox\z@=\hbox{%
  6322. %
  6323.   \A@=\wd\lastobjectbox@                        %1
  6324.   \B@=\dp\lastobjectbox@ \advance\B@\ht\lastobjectbox@
  6325.   \ifdim \A@=\z@ \count@@=\m@ne
  6326.   \else \dimen@=\sdX\dX \divide\dimen@\A@ \count@@=\dimen@ \fi
  6327.   \Spread@@
  6328. %
  6329.   \ifdim\dX>\z@ \advance\Xc-\wd\lastobjectbox@ \fi            %2
  6330. %
  6331.   \dimen@=-\sdX\wd\lastobjectbox@                    %4
  6332.   \multiply\dimen@\K@dYdX \divide\dimen@\K
  6333.   \ifdim\dX>\z@ \advance\Yc\dimen@ \advance\Yc-\Leftness@\dimen@
  6334.   \else \advance\Yc\Leftness@\dimen@ \fi
  6335. %
  6336.   \dimen@=\wd\lastobjectbox@ \A@=\sdX\dX \advance\A@-\dimen@        %3
  6337.   \B@=\sdX\dimen@ \multiply\B@\K@dYdX \divide\B@\K \advance\B@-\dY \B@=\sdY\B@
  6338.   \count@=\count@@ \advance\count@\m@ne
  6339.   \ifnum\z@<\count@ \divide\A@\count@ \divide\B@\count@ \fi
  6340.   \A@=-\sdX\A@ \B@=\sdY\B@ \wd\lastobjectbox@=\A@
  6341. %
  6342.   \kern\Xc \count@=\z@                            %5
  6343.   \loop@\ifnum\count@<\count@@ \advance\count@\@ne
  6344.    \raise\Yc\copy\lastobjectbox@ \advance\Yc\B@ \repeat@}%
  6345. %
  6346.  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
  6347.  
  6348. % Using vtop:
  6349.  
  6350. %    %0 start box...
  6351.  
  6352. %    %1 compute initial adjustment (X  right and Y up) and...
  6353. %        A := w, B := h+d, N [\count@@] = floor(|dY| / B),
  6354. %       and run user supplied Spread;
  6355.  
  6356. %    %2 adjust vertically for first filler size:
  6357. %        if dY<0 then Y := Y-h else Y := Y+d;
  6358.  
  6359. %    %3 recompute the move dimensions (B up and A right):
  6360. %        B := sdY((|dY| - (h+d)) / (N-1)),
  6361. %        A := sdX|sdY(h+d)*dX/dY - dX| / (N-1),
  6362. %       and set the filler box to have h := B, d := 0;
  6363.  
  6364. %    %4 adjust first filler horizontally:
  6365. %        X :=  X + (if dY<0 (1-Upness) else Upness)*A - Leftness*w
  6366.  
  6367. %    %5 output first filler adjusted X,Y and the following N-1 each -B
  6368. %       further down and moved A more right than the previous;
  6369.  
  6370. % ...and finally end object with usual bravour!
  6371.  
  6372. %\xydef@\straightv@{\setbox\z@=\vtop{%                    %0
  6373. %
  6374. %  \A@=\wd\lastobjectbox@                        %1
  6375. %  \B@=\dp\lastobjectbox@ \advance\B@\ht\lastobjectbox@
  6376. %  \ifdim \B@=\z@ \count@@=\m@ne
  6377. %  \else \dimen@=\sdY\dY \divide\dimen@\B@ \count@@=\dimen@ \fi
  6378. %  \Spread@@
  6379. %
  6380. %  \ifdim\dY<\z@ \advance\Yc-\ht\lastobjectbox@                %2
  6381. %  \else \advance\Yc\dp\lastobjectbox@ \fi
  6382. %
  6383. %  \dimen@=\dp\lastobjectbox@ \advance\dimen@\ht\lastobjectbox@        %3
  6384. %  \B@=\sdY\dY \advance\B@-\dimen@
  6385. % \A@=\sdY\dimen@ \multiply\A@\K@dXdY \divide\A@\K \advance\A@-\dX
  6386. %  \A@=\sdX\A@ \count@=\count@@ \advance\count@\m@ne
  6387. %  \ifnum\z@<\count@ \divide\B@\count@ \divide\A@\count@ \fi
  6388. %  \B@=\sdY\B@ \A@=\sdX\A@ \ht\lastobjectbox@=\B@ \dp\lastobjectbox@=\z@
  6389. %
  6390. %  \ifdim\dY<\z@ \advance\Xc\A@ \advance\Xc-\Upness@\A@            %4
  6391. %  \else \advance\Xc\Upness@\A@ \fi
  6392. %  \advance\Xc-\Leftness@\wd\lastobjectbox@
  6393. %
  6394. %  \null \kern-\Yc \count@=\z@                        %5
  6395. %  \loop@\ifnum\count@<\count@@ \advance\count@\@ne
  6396. %   \nointerlineskip \moveright\Xc\copy\lastobjectbox@ \advance\Xc\A@ \repeat@}%
  6397. %  %
  6398. % \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
  6399. \DOCMODE)
  6400.  
  6401. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6402.  
  6403. Fix to the |\straightv@| bug.
  6404.  
  6405. \DOCMODE(
  6406. \xydef@\straightv@{\setbox\z@=\vtop{%                    %0
  6407. %
  6408.   \A@=\wd\lastobjectbox@                        %1
  6409.   \B@=\dp\lastobjectbox@ \advance\B@\ht\lastobjectbox@
  6410.   \ifdim \B@=\z@ \count@@=\m@ne
  6411.   \else \dimen@=\sdY\dY \divide\dimen@\B@ \count@@=\dimen@ \fi
  6412.   \Spread@@
  6413. %
  6414.   \dimen@=\dp\lastobjectbox@ \advance\dimen@\ht\lastobjectbox@        %3
  6415.   \B@=\sdY\dY \advance\B@-\dimen@
  6416.   \A@=\sdY\dimen@ \multiply\A@\K@dXdY \divide\A@\K \advance\A@-\dX
  6417.   \A@=\sdX\A@ \count@=\count@@ \advance\count@\m@ne
  6418.   \ifnum\z@<\count@ \divide\B@\count@ \divide\A@\count@ \fi
  6419.   \B@=\sdY\B@ \A@=\sdX\A@ \ht\lastobjectbox@=\B@ \dp\lastobjectbox@=\z@
  6420. %
  6421. %  \dimen@ still holds the unadjusted \ht+\dp
  6422. %
  6423.  \ifdim\dY<\z@ 
  6424.   \advance\Yc\dimen@ \advance\Yc\Upness@\B@
  6425.  \else
  6426.   \advance\dimen@\Upness@\B@ \advance\Yc-\dimen@ \advance\Yc\B@
  6427.  \fi
  6428.  \advance\Yc\B@ 
  6429. %
  6430.  \ifdim\dX<\z@ \else \advance\Xc-\wd\lastobjectbox@ \fi
  6431. %
  6432.   \null \kern-\Yc     \count@=\z@      %5
  6433.   \loop@\ifnum\count@<\count@@ \advance\count@\@ne
  6434.    \nointerlineskip \moveright\Xc\copy\lastobjectbox@ \advance\Xc\A@
  6435.   \repeat@}%
  6436.   %
  6437.  \ht\z@=\z@ \wd\z@=\z@ \dp\z@=\z@ {\Drop@@}}
  6438. \DOCMODE)
  6439.  
  6440. \DOCMODE2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6441.  
  6442.  
  6443.  
  6444. \section*{End \& log}
  6445.  
  6446.     \XY-pic ends with a message saying so.
  6447.  
  6448. \DOCMODE(
  6449. \message{XY-pic loaded}\xyuncatcodes \endinput
  6450. \DOCMODE)
  6451.  
  6452.     \XY-pic is maintained using the RCS ``Revision Control System'' by
  6453.     Walther F.~Tichy.  The following is the revision history since the
  6454.     first release to Usenet.
  6455.  
  6456. \DOCMODE(
  6457. % $Log: xy.doc,v $
  6458. % Revision 2.12  1994/10/25  11:55:12  kris
  6459. % Interim release just before v3 [works with AMS-LaTeX 1.2]...
  6460. %
  6461. % Revision 2.11     1994/07/05  10:37:32  kris
  6462. % Third 3beta release [bug fixes].
  6463. % Experimental graph feature included (for ECCT-94 presentation).
  6464. %
  6465. % Revision 2.10     1994/06/15  12:55:07  kris
  6466. % Second 3beta release: bug fixes.
  6467. %
  6468. % Revision 2.9    1994/06/09  14:59:19  kris
  6469. % Release 3beta.
  6470. %
  6471. % Revision 2.8    1994/04/11  09:31:09  kris
  6472. % Second (bug fix) 3alpha release [corrected].
  6473. %
  6474. % Revision 2.7    1994/03/08  02:06:01  kris
  6475. % Release 3alpha.
  6476. %
  6477. % Revision 2.6.9.1  1994/03/07    04:22:46  kris
  6478. % Last internal 3alpha and pre-2.7 release.
  6479. %
  6480. % MAJOR REWRITE and REORGANISATION:
  6481. % File xypic.doc split into separate files: xy.doc for `kernel' and other
  6482. % files with the `extensions' and `features'.
  6483. % Documented in special DOCMODE LaTeX-based format supported by xydoc.sty.
  6484. %
  6485. % Revision 2.6.1.1  1992/07/01    07:08:24    kris
  6486. % Send to EuroTeX '92...
  6487. %
  6488. % Revision 2.6    1992/06/24  01:23:34  kris
  6489. % Added hooks using font xyqc10.
  6490. % Added new POSitions: * and !.
  6491. % Added triple lines \Ssolid and \Ddashed.
  6492. %
  6493. % Revision 2.5    1992/02/24  03:30:54  kris
  6494. % Fixed bugs in \Direction calculation logic...
  6495. % Added (FACTOR) to \rotate to allow arbitrary rotation.
  6496. % ` intermediate points now accept an optional /RADIUS argument.
  6497. % Added \Tip with wide tip.
  6498. % [See ChangeLog for further details].
  6499. %
  6500. % Revision 2.4    1992/01/22  02:15:10  kris
  6501. % Fixed bugs [with thanks]:
  6502. % No spurious arrow heads with LaTeX: \pit now undefined [Werner Struckmann]
  6503. % \Solid works: sets \Density [Dave Bowen]
  6504. % Short diagonal lines work...major rewrite of \connectv@ [Eric Domenjoud]
  6505. %
  6506. % Revision 2.3    1992/01/13  23:28:12  kris
  6507. % Swapped definitions of \ddtoX and \uutoX [found by Nico Verwer].
  6508. % Diagonal lines were wrong [Eric Domenjoud].
  6509. %
  6510. % Revision 2.2    1992/01/09  04:05:40  kris
  6511. % Still problems with rules in frames and horizontal/vertical \solids. Grrr.
  6512. %
  6513. % Revision 2.1    1992/01/02  14:54:07  kris
  6514. % Release version.
  6515. %
  6516. % Revision 1.40     1991/12/17 04:53:23 kris
  6517. % Version distributed as `final draft' on Usenet.
  6518. \DOCMODE)
  6519.  
  6520. \DOCMODE3%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6521.  
  6522. % Tell Emacs that this is a LaTeX document and how it is formatted:
  6523. % Local Variables:
  6524. % mode:latex
  6525. % fill-prefix:"\t"
  6526. % fill-column:77
  6527. % paragraph-separate:"^[ \t\f]*$\\|^[^\t]\\|\\\\\\\\\\|\\$\\$\\|[^\n\\\\][%&]"
  6528. % paragraph-start:"^[ \t\f]*$\\|^[^\t]\\|\\\\\\\\\\|\\$\\$\\|[^\n\\\\][%&]"
  6529. % TeX-parse-self:nil
  6530. % End:
  6531.